Raku rebless artık miras alınan sınıflarla çalışmıyor


9

Bu iş parçacığında verilen kod artık çalışmıyor: Perl 6'da bir nesneyi nasıl korusun?

Bu kod parçasını geçen yıl yazdım ve o zaman işe yaradı. Şimdi değil:

class Person { ; }
class Woman is Person { ; }
my $tom = Person.new;
my $lisa = Woman.new;

say $tom.^name;  # -> Person
say $lisa.^name; # -> Woman

Metamodel::Primitives.rebless($tom, Woman);
# -> New type Woman for Person is not a mixin type

Devralınan sınıflarla çalışması gerektiği için hata mesajı anlamlı değildir. En azından öyleydi.

Dokümantasyon yardımcı değildir; https://docs.raku.org/routine/rebless


Bir regresyon hatası olabilir. Muhtemelen bir Rakudo sorunu olarak rapor etmek en iyisidir.
jjmerelo

Geçen Şubat ayında bazı değişiklikler yapıldı: github.com/perl6/nqp/blob/…
jjmerelo

Ayrıca, belgeleri @jnthn answer docs.raku.org/type/Metamodel::Primitives adresine işaret eden bir dipnotla güncelledim . Teşekkürler, raiph
jjmerelo

Yanıtlar:


11

kalıtsal sınıflarla çalışması gerekiyordu

Asla bu kadar genel olması gerekmiyordu. Bu API'yi tasarladım ve ilk etapta uyguladım ve sadece mixinlerin bir uygulama detayı olarak tasarlandı.

Çok yakın zamana kadar, dil spesifikasyonu test paketinin bir parçası değildi - ve bir parçası haline geldiğinde, şimdiki, daha kısıtlayıcı, anlambilimine sahipti. Üzerindeki kısıtlamalar performans nedenleriyle önemlidir: bir türün bir mixin işleminin hedefi olabilecek bir tür olmadığını bildiğimizde, o nesne üzerindeki öznitelik erişimlerini daha basit bir şeye JIT-derleyebiliriz ( her özellik değişiklikten önce erişir ve şimdi yalnızca mixin hedef türlerinde ödemek zorunda).

Sınıfı oluşturmak için MOP kullanarak orijinal programı çalışacak şekilde değiştirmek mümkündür. Aslında, aşağıdakiler tam olarak orijinal bir program değildir; Çok fazla MOP kaynak plakasından kaçınmak için bir isimsiz rol olarak alt sınıfta nasıl yöntemler sağlayabileceğini göstermek için küçük bir değişiklik yaptım.

class Person { method m() { "person" } }
constant Woman = do {
    my \w = Metamodel::ClassHOW.new_type(:is_mixin, :name<Woman>);
    w.^add_parent(Person);
    w.^add_role(role { method m() { "woman" } });
    w.^compose()
}
my $tom = Person.new;
my $lisa = Woman.new;

say $tom.^name;  # -> Person
say $lisa.^name; # -> Woman

say $tom.m; # person
Metamodel::Primitives.rebless($tom, Woman);
say $tom.m; # woman

Orijinal programın en anlamsal olarak doğrudan düzeltmesi bu olsa da, daha kısa bir yol var: bir mixin türü oluşturmak ve onu döndürmek için yazım nesnesindeki butoperatörü kullanın Personve ardından adını beğeninize göre değiştirin:

class Person { method m() { "person" } }
constant Woman = Person but role { method m() { "woman" } }
BEGIN Woman.^set_name('Woman');

my $tom = Person.new;
my $lisa = Woman.new;

say $tom.^name;  # -> Person
say $lisa.^name; # -> Woman

say $tom.m;
Metamodel::Primitives.rebless($tom, Woman);
say $tom.m;

Zaten orijinalinden daha fazla bir satır.


constant Woman = Person but role …Bunun yapılabileceğini fark etmedim. Ve böylece ancak BEGINhat için, Raku da JS tarzı bir prototip paradigması yapabiliyor!
user0721090601

Tamam. Açıklama için teşekkürler. Docs.raku.org/routine/rebless oldukça işe yaramaz olduğu için belgelere gireceğini umuyorum ... Kısa süre içinde «Başlangıç ​​Raku» nu güncelleyeceğim.
Arne Sommer

@ user0721090601 Raku, S12: "hem sınıf tabanlı hem de prototip tabanlı OO programlama" özelliğini destekleyerek destekler . Ancak, anahtar kelimeyi kullanarak nesneler oluşturursanız,class S12'den tekrar alıntı yaparsanız : "varsayılan olarak, Musınıftan türetilen oldukça standart bir sınıf modelini destekler ... bless... çağırır ... YAPI yordamları ... varsayılan BUILD anlambilimleri kaynağından devralındı Mu". Özetle, Raku'nun A) "bataklık standart sınıf tabanlı OO'yu bile sadece birkaç satırlık kodla" ve B) "prototip tabanlı OO" yu ciddi şekilde desteklediğini söylemek daha doğru olur .
Ocak'ta raiph

Değişiklikleri kırma konusundaki görüşüm için raku-musings.com/reblessed.html adresine bakın .
Arne Sommer

5

Tam olarak ne olduğu reblessve bu konuda ne yapılacağı hakkında yetkili tartışma için jnthn'ın cevabına bakın .

işe yaradı ... Şimdi çalışmıyor .. Hata mesajı anlamsız ... kalıtsal sınıflarla çalışması gerekiyordu ... En azından öyleydi ... Dokümantasyon yardımcı değil

Bu (ultra uzun!) Cevap , Raku programlama dili ve Rakudo derleyici ve docs.raku.org içeriği gibi ilgili eserler üzerinde çalışmanın altında yatan TDD yaklaşımının ilkeleri ve uygulamaları hakkında daha fazla tartışmak isteyenlere okunmaya değer olabilir. .

Bu cevap, Arne'nin orijinal sorunun belirli bölümlerine ve bu cevabın önceki bir versiyonuna yanıt olarak yazdıkları yorumlara özel cevaplar olarak yapılandırılmıştır. Amacım Arne için daha yararlı hale getirmekti, umarım hala başkaları için yararlıydı.

Arne: Bu iş parçacığında verilen kod artık çalışmıyor: Raku'da bir nesneyi nasıl kutsamayabilirim?

Bu SO bağlamak için SO kabul edilen cevabı güncelledim.

Arne: Geçen yıl bu kod parçasını yazdım ve o zaman işe yaradı. Şimdi öyle değil

İlgili değişiklik, jnthn'ın yazdığı Nisan 2019 tarihli bir taahhütte tartışıldı :

Son zamanlarda, bir reblessoperasyonun hedefi olan türlerin, optimizasyona yardımcı olmak için açıkça mixin hedef türleri olarak oluşturulması gerekiyordu. ...

In "özel türdeki artık işe görünüyor için Rebless" 11 gün kapanış rakudo GH konuyla önce bir açıklama şunları yazdı:

Belirtilen is_mixinargümanın iletilmesini sağlamanız gerekir ClassHOW.new_type... Bunu sınıf sözdizimi ile yapmanın bir yolu yoktur, bu yüzden rebless'in hedef türü MOP kullanılarak da birleştirilmelidir.

(Önerilerini nasıl yapacağınıza ilişkin notlar için yukarıdaki bağlantıyı tıklayın.)

Bu konu da biraz daha tartışıldı, işe yaradı ... aniden ... dokümantasyon ... aşağıdaki çağrı bölümünü belgelemeliydi .

Arne: kalıtsal sınıflarla çalışması gerekiyor. En azından öyleydi.

Kızartma - r epository o f bir ll s Pec t ESTS - Raku kodu yapmak için beklenen belirler. ( St arasında roa st olarak okunabilir s upposed t o s).

Başka bir Nisan 2019 mesajında jnthn şunu yazdı:

İçin önceden bir spesifikasyon yoktu Metamodel::Primitives.rebless. Ben ettik bu spectest eklendi artık çok düşük olduğunu bu yüzden. Bu, artık neyin işe yarayabileceğinin bir tanımı olduğu anlamına geliyor.

Rakudo'nun davranışının yürütülebilir bir test paketi tarafından belirtilmesi, @ Larry'nin Raku'nun güvenilir davranmasını sağlama yaklaşımının temel bir parçasıdır [1] ve derin etkileri vardır [2] .

Bu değişikliğin yaygın olarak kullanılan bir modül üzerindeki etkisi

İşte popüler Inline :: Perl5 modülü için ortaya çıkan bu değişikliğin etkisinin bir fotoğrafı.

Nisan 2019'da, niner üzerindeki etki üzerinde bir rakudo GH sorunuInline::Perl5 açtı ve aşağıda niner ve jnthn arasındaki alışverişin bazı önemli noktalarını çıkardım.

(Orijinal bağlamda önemli olan, ancak bu SO bağlamında dikkat dağıtan bazı şeyleri elettim. Lütfen bu alıntıdan orijinal sohbeti tam olarak anladığınızı varsaymayın . Şüpheniz varsa bağlantıyı tıklayın. )

niner: TBH burada yaptığım muhtemelen her zaman biraz balık oldu ... Hatta olabilir ... [on] kurtulmak olabilir ... Zaten konuşlandırılmış tutmak iyi olurdu Inline :: Perl5 sürümleri çalışıyor ve çalışıyor .

jnthn: için önceden bir spesifikasyon yoktu Metamodel::Primitives.rebless. [A] spektrumu ekledim, böylece şimdi var. Bu, şimdi neyin çalışması beklenebileceğine ve Inline :: Perl5'in güvenebileceğine dair bazı tanımların olduğu anlamına gelir.

Bilinmeyen adlandırılmış parametreler yok sayıldığından, ancak :mixinönceki Rakudo sürümlerinde gerekli olmadığından, önceki Rakudo sürümlerinin yanı sıra gelecek olanlarda da çalışabilecek yeni bir Inline :: Perl5 sürümü yapmak mümkün olacaktır, bu yüzden en azından olabilir arka compat.

Mevcut Inline :: Perl5 sürümleri için işleri çalışmaya devam etmenin bir yolu olduğunu sanmıyorum ...

niner: Maalesef geçmek :mixinbu durumda yardımcı olmaz çünkü rebless yaratılanın bir alt sınıfında yapılır Metamodel::Primitives.create_type. Alt sınıf normal olanı kullanır Perl6::ClassHOW.

Ben ilk etapta rebless hack kurtulmak için büyük bir refactor üzerinde çalışıyorum. Bu sorunu tekrar açıyorum, böylece yayın yöneticisi, rakudo'nun yayın adayı üzerinde çalışan Inline :: Perl5'in olmadığının farkında.

jnthn: MOP kullanarak bu sınıfı oluşturuyor musunuz? Sen geçebilir :is_mixiniçin Perl6::ClassHOW.new_typeeğer öyleyse.

niner: Hayır, bu durum için:class Bar is Foo { }

Dokümanlar ile yardım

Bu cevabın altındaki bir yorumda şunları yazdınız:

Dokümantasyon bölümünde yardımcı olabilirim

Bu bana SOQ'nuzun kalbindeki soruna çok uygun ve yararlı bir yanıt gibi geliyor. Umarım bu başarıya ulaşacak kadar şanslıyız.

bu yardımcı olursa

Imo teknik yazınız mükemmel, bu yüzden umarım geliştirmekle ilgilenen başkalarıyla çalışmanın sonucu harika bir şey olurdu.

Docs.raku.org içeriğinde temel kısıtlamalar

Bu çok basit cevabın geri kalanını bu kadar basit görünen bir soruya yazmamın ve Jonathan'ın cevapladıktan sonra ilk olarak sildikten sonra eski haline getirme nedenimin büyük bir kısmı, üzerinde çalışmanın altında yatan TDD yaklaşımının ilkelerini ve uygulamasını tartışmaktı . Raku programlama dili ve Rakudo derleyicisi ve docs.raku.org içeriği gibi ilgili eserler .

Aiui, Raku'da işlerin nasıl çalışması gerektiği ve gerçekten Rakudo'da nasıl çalıştıkları ve işlerin docs.raku.org'da nasıl belgelenmesi gerektiği arasındaki arzu edilen ilişki aşağıdakilere kaynar:

  • Her şeyin sonsuza dek gönüllü bir projenin temel doğasına tabi olduğu varsayılmalıdır ZORUNLU ; ve bu kısıtlama dahilinde:

  • Davranış kızartma GEREKEN belgelendirilmesi ve diğer davranış olmamalıdır.

(Mevcut gönüllü zaman, ilgi ve fikir birliği göz önüne alındığında, zaman zaman kızartma kapsamında olmayan düzgün bir QA'd Rakudo'nun davranışını belgelemek için istisnalar yapılır. Mevcut uygulamada bu, yayınlanan bir Rakudo Star'daki bir Rakudo versiyonunun davranışı anlamına geliyor gibi görünmektedir.)

Yararsız belgeler

Belgeler yardımcı olmuyor

Bunu adil bir yorum olarak değerlendirdim. Her şey göz önüne alındığında, sorunuzu yazarken olduğu gibi belgeler yardımcı olmadı.

dokümantasyon işe yaramazdı [2018'de]

Bu çok farklı bir ifadedir.

reblessO sırada kızartma girişi yoktu .

Üzerinde docs.raku.org sayfa varsa rebless vardı o 2018 yılında olduğu gibi davranışını tarif, o olurdu yararsız daha kötü yanlış o anda geçerli davranış desteklenmiştir öneririm çünkü. Gerçekte, Rakudo'nun gelecekteki bir versiyonunda makul bir olasılık olmadan kırılması için bir kapsam vardı, 2018 davranışı çekirdek geliştiriciler tarafından eski haline getirilecekti. Gerçekten de bu geçti: 2018'den itibaren desteklenmeyen davranışı kırıldı ve eski haline getirilmedi.

Bu nedenle, docs.raku.org'a neyin ait olduğu ve neyin (yukarı bakınız) olmadığı konusundaki fikir birliği göz önüne alındığında, reblesssayfasının yapabileceği en yararlı şey ya hiç belge vermemek ya reblessda belki de daha iyisi için bir sayfa eklemekti. emin olunuz ki değil davranışını tarif eder. Durum buydu: sayfa vardı; doğrudan yardımcı olmadı; ve bu tartışmasız hiçlikten daha iyiydi.

(İşlerin henüz daha iyi olduğunu hayal etmek kolaydır. Örneğin, işlevleri belgeleyen sayfalar en son Rakudo Star'da Rakudo sürümünde bu işlevle ilişkili test kapsamının durumunu belgeleyen bir yüzdeyi içeriyorsa?% 0'ı hemen bir okuyucuyu ipucu verebilir Bu dokümanın özelliği hayal etmek kolay olsa da , bunu kimin uygulayacağını bilmenin de bir takvim yılı veya daha fazla gayretli çalışma alabileceğini hayal etmek de aynı derecede kolay. ve yararlı bir şekilde uygulamak ve dağıtmak için işbirliği yaptık ve bu halk başka şeylerin daha önemli olduğunu düşünüyor.)

işe yaradı ... aniden işe yaramadı ... belgeler ... çağrıyı belgelemeli

işe yaradı

İşe yaradı "şans" idi.

aniden işe yaramadı

Çünkü Rakudo geliştirildi.

belgeler ... çağrıyı belgelemelidir

Daha önce açıklandığı, şimdiki toplum uzlaşma ve / veya çalışma pratiği aiui geçerli: dokümantasyon GEREKEN belgelemek belirli bir sürümü çağrısı, yani bir kızartma son Rakudo Star'da Rakudo sürümü için 'd davranışı; ve diğer sürümlerde belge davranışları olabilir.

ve başka bir şeye gönderme

Aiui, mevcut fikir birliği ve / veya çalışma uygulaması, bazılarının "zayıf" dokümanı katkıları olarak düşünebilecekleri, örneğin kısa, aceleyle yazılmış içerik ve / veya dokümanlar dışındaki bağlantılar gibi, gönüllülerin derhal bir değişikliğin yansıtmak için gerekli olduğunu düşünmeleri halinde tanıtılabilir kullanıcı tarafından dile getirilen bazı endişeler (örneğin bu SO) ve "zayıf" değişikliği yapmanın hiçbir şey yapmamaktan daha iyi olacağıdır. Elbette onu geliştirmek için bir PR yapabilirsiniz (ya da bir değişikliğin bu kadar "zayıf" olduğunu düşünüyorsanız, durumu daha da kötüleştirirse geri almak için).

2019.11'deki değişikliklere referans sayımla 7 ay

(Benim sayımla da böyle bir şey, ancak aynı davranışta kırılma ile 2019.03.1 olduğunu iddia eden bir derleyici gördüm. [3] )

Bence JJ dokümanı değiştirdi ve sadece jnthn'in değişime nasıl uyum sağlayacağı hakkındaki yorumunu yanlış yorumladı. Şu anda hiçbir şeyden daha iyi olduğunu düşünüyorum ama güncelleme için sabırsızlanıyoruz. :)

Dipnotlar

[1] Larry , 2000 "Soğan Durumu" konuşmasında Raku'ya yol açan projeyi ilk duyurduktan birkaç dakika sonra şöyle dedi :

Soru: [Raku] 'nun teknik özellikleri var mı?

Larry: Özellikle vurgulamak istediğimiz şey ... belki de şu anki regresyon testimizi geliştirmek gibi [dil tasarımı] spesifikasyonu değil ... dilin gerçekte ne anlama geldiğini ve gerçekten dışarı çıkıp tüm köşeleri keşfetmek ve çatlaklar ve "Bu [Raku], bu [Raku] değil” ”deyin ve aslında makine tarafından okunabilen bir özelliğimiz var. Ve bu benim için, insan tarafından okunabilir olan şeydeki sözlerin söylediklerinden çok daha önemli.

[2] Tabii ki, kızartma sadece belirli bir kullanıcı için, testleri kullanıcının ihtiyaçlarını yeterince karşıladığı takdirde iyi çalışır. Arne'nin problemi, kapsama alanındaki deliklerin nasıl şaşırtıcı olabileceğini göstermektedir. Bu deliklerin 2018'de dururken tartışılması için bkz . Teknik Özellikler, Sürüm Oluşturma, Değişiklikler ve… Kırılma . İyi haber şu ki, kızartma, Raku'da belirli değerlere sahip ifadelerin veya yapıların belirli bir şey yaptığını test etmek için yazılmış çok sayıda birim testtir. Bu nedenle, bireylerin veya şirketlerin test kapsamını iyileştirmek için yeni testlere katkıda bulunması kolaydır. Ve hepsi sürüm kontrolü altında (git), bu nedenle özel aşağı akış etiketleri, dalları ve çatalları uygulanabilir, sürdürülebilir ve yönetilebilir. (Nitekim bu dil sürümleri (nasıl yenilikler Christmas, Diwali, Eid(?), Vs.) yönetilir.)

[3] Düzenli newclass is oldclasssözdizimi kullanılarak oluşturulmuş yeni bir sınıfı, hem iş (dizüstü bilgisayarımda) hem de çalışmadığı (repl.it'te) olduğunu iddia eden derleyiciler kullanarak yeniden kutlamaya çalıştım2019.03.1 . (Presumb.it derleyici, derleyici kaynak kodunun bir sürümünü veya derlenmiş bir ikili dosyayı kurdu, derleyicinin sürümü güncellendikten kısa bir süre sonra ana kafadan alındı ​​ve 2019.03.1değişiklik kırıldı. Çevrimiçi raku repl'lerini yayınladım - kazara keşfettim - bu durumla ilgili rahatsız edici bir şey yok, ancak $RAKU.compiler.verbose-configyeni bağladığım işlenmiş / kırık çıkışlarda kullanılan yönteme duyulan ihtiyacı güçlendirdi .)


Belgenin işe yaramaz olduğu için "rebless" ın nasıl çalıştığını anlamaya çalıştığımda bu makaleyi buldum: stackoverflow.com/questions/44486985/… Ve o zaman işe yaradı. Ve sonra aniden işe yaramadı ve belgeler hala işe yaramadı. Yine de, çağrıyı belgelendirmesi gerektiği ve başka bir şeye atıfta bulunmaması gerektiği gibidir. Ve 2019.11'deki değişikliklere referans sayımla 7 ay.
Arne Sommer

Yardımcı olursa, dokümantasyon kısmına yardımcı olabilirim.
Arne Sommer

@ArneSommer Lütfen dokümanlardaki Yardım ile başlayarak cevabımdaki yeni bölümlere bakın .
raiph

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.