Nil'de herhangi bir yöntemi çağırabilirim ve bu yanlış geliyor


14

Son zamanlarda bir komut dosyası hata ayıklama önemli zaman geçirdim ve nihayet sorunu buldum, bunun gibi görünen kod nedeniyle oldu:

class Foo {
    has $.bar;
    method () {
        # do stuff
        $!.bar;
    }
}

Sorunun $!.barya $!barda olması gerektiği ile ilgili olduğu ortaya çıktı $.bar. Bunu anladım.

Ama bu neden ölmüyor ?

Daha ayrıntılı olarak bu baktığımızda, burada sorun gibi görünüyor Ben (varolmayan) yöntemini çağırmak çalışıyorum olmasıdır barüzerinde $!bu noktada, Nilherhangi bir hata olmamıştır çünkü.

Aslında ben üzerinde istediğiniz herhangi yöntemini çağırabilirsiniz Ve görünüşe Nilve hepsi sessizce dönüş Nilgibi şeyler de dahil olmak üzere, Nil.this-is-a-fake-methodve Nil.reverse-entropy(123).

Bu bir özellik mi? Eğer öyleyse, mantığı nedir?

Yanıtlar:


13

Amaçlanmıştır ve belgelenmiştir, evet. Bunun başlığı Nil"Değerin veya iyi huylu bir hatanın olmaması" dır ve sınıf belgelerinden bahsedilir

NilVar olmayan bir yöntemin çağrılması ve sonuç olarak herhangi bir abonelik işlemi başarılı olur ve geri döner Nil.

say Nil.ITotallyJustMadeThisUp;  # OUTPUT: «Nil␤» 
say (Nil)[100];                  # OUTPUT: «Nil␤» 
say (Nil){100};                  # OUTPUT: «Nil␤»

Sinopsis 2 , " Nilgeri dönüşlerde tanımlanmamış herhangi bir yöntem çağrısı yapar Nil, böylece Nilyöntem çağrı zincirlerini yayar. Aynı şekilde Nilgeri dönüşlerde herhangi bir abonelik işlemi Nil", bu nedenle her adımda $foo.Bar()[0].Baz()kontrol Nilveya özel "Nil-safe" gerektirmeyen ifadelere izin veriyor gibi görünür. msgstr "yöntem çağrısı ve abone operatörleri.


4
Aslında. Ve uzun zaman önce de zaten: github.com/rakudo/rakudo/commit/174727377f (Aralık 2013) Ayrıca ilgili spekülasyona da bakınız: design.raku.org/S02.html#Nil
Elizabeth Mattijsen

1
@ElizabethMattijsen ah, sanırım S02'nin cevabı var. "Herhangi bir tanımsız yöntem çağrısı Nildöner Nil, böylece Nilyöntem çağrı zincirlerini aşağı yayılır." Bu nedenle $foo.Bar().Baz().Blah(), her adımda nil testlerine veya özel bir ?.operatöre (sonunda nil'i doğru şekilde işlediğiniz sürece) yapabilmeniz amaçlanmıştır . Bunu ben de düzenleyeceğim, teşekkürler.
hobbs

1
NilHata yapmayan ve sadece daha fazlasını geri getiren A , Nilbenzer şekilde kullanıldığı Obj-C ve NS Frameworks'te oldukça yaygın bir şekilde kullanılır - Nil'den geçmeye devam eden zincirleme çağrılara izin verir. İstisnaların ve onları yakalamanın kesin performans cezalarını bilmiyorum, ama tahminim Nilzincirleme daha az esnek olursa daha verimli olabilir.
user0721090601

1
(ama bu tamamen bilgisiz bir tahmin, bu yüzden lizmat veya jnthn'ın bana yanlış olduğumu ve kapatmam gerektiğini söylemekten mutluluk duyuyorum :-))
user0721090601

2
NilSınıf sahip FALLBACK docs.raku.org/language/typesystem#index-entry-FALLBACK_(method) olan döner bir yöntem, Nil. Temel olarak, bir yöntem bulunamadığından bir istisna oluşturulmadan hemen önce bir denetim FALLBACKyapılır ve varsa çağrılır.
Elizabeth Mattijsen

5

Bu soru (ve hobbs'un cevabı) da beni huzursuz etti: sonunda https://docs.raku.org/language/traps buldum : atamanın Nilgenellikle farklı bir değer ürettiğini açıklıyor Any. Aşağıdaki temel REPL etkileşimi de bunu göstermektedir:

> my $foo = Nil
(Any)

> $foo.bar
No such method 'bar' for invocant of type 'Any'
  in block <unit> at <unknown file> line 1

> my $bar := Nil
Nil

> $bar.baz
Nil

((Arasındaki fark =ve :=: burada kaplıdır https://docs.raku.org/language/containers#Binding ))

... yani genel fikir şu ki, 'eksik değer veya iyi huylu başarısızlık' normal kodda benden (ve belki de siz?) çok daha az yaygındır: aniden regex ile çalışacağınız zaman meydana gelir doğrudan ve doğrudan isteme yöntemleri ile ilgili kaza durumunuzla eşleşir $!.

Bu arasındaki fark hakkında beni daha haberdar Nilve Anyve sağlanan mantığı bana daha mantıklı.


2
Nilbir kapsayıcıyı varsayılan durumuna ayarlar. Varsayılan değeri değiştirebilirsiniz. my $foo is default(42) = 5; $foo = Nil; say $foo; # 42
Brad Gilbert
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.