J'ai passé beaucoup de temps à déboguer un script récemment, et quand j'ai finalement trouvé le problème, c'était à cause du code qui ressemblait à ceci:
class Foo {
has $.bar;
method () {
# do stuff
$!.bar;
}
}
Il s'est avéré que le problème était avec cela $!.bar
, qui aurait dû être soit $!bar
ou $.bar
. J'ai compris.
Mais pourquoi cela ne meurt-il pas ?
En regardant plus en détail, il semble que la question ici est que je suis en train d'appeler une méthode (inexistante) bar
sur $!
, qui à ce stade est Nil
parce qu'il n'y a pas eu d'erreurs.
Et il semble que je puisse réellement appeler n'importe quelle méthode que je veux Nil
et ils reviennent tous en silence Nil
, y compris des trucs comme Nil.this-is-a-fake-method
et Nil.reverse-entropy(123)
.
Est-ce une fonctionnalité? Si oui, quelle est la justification?
Nil
retoursNil
, de sorte que seNil
propage vers le bas les chaînes d'appels de méthode." Il est donc prévu que vous puissiez faire$foo.Bar().Baz().Blah()
sans avoir besoin de tests nil à chaque étape ou d'un?.
type spécial d'opérateur (tant que vous gérez correctement nil à la fin). Je vais le modifier, merci.Nil
qui ne fait pas d'erreur et renvoie simplement plusNil
obtient une utilisation assez étendue dans Obj-C et les cadres NS où il est utilisé d'une manière similaire - permet des appels chaînés qui continuent à passer sur Nil. Je ne connais pas les pénalités de performances exactes des exceptions et de leur capture, mais je suppose que leNil
chaînage peut être plus efficace, mais moins flexible.Nil
classe a une méthodeFALLBACK
docs.raku.org/language/typesystem#index-entry-FALLBACK_(method) , qui renvoieNil
. Fondamentalement, juste avant qu'une exception ne soit levée car une méthode est introuvable, une vérificationFALLBACK
est effectuée et appelée si disponible.Cette question (et la réponse de Hobbs) m'a également fait me sentir ... mal à l'aise: j'ai finalement trouvé https://docs.raku.org/language/traps : cela explique que l'attribution
Nil
produit généralement une valeur différenteAny
. L'interaction REPL de base suivante le démontre également:((la différence entre
=
et:=
est couverte ici: https://docs.raku.org/language/containers#Binding ))... donc l'idée générale est que la `` valeur absente ou l'échec bénin '' est beaucoup moins répandue dans le code normal que je (et peut-être vous aussi?) craignais soudainement: cela se produit cependant lorsque vous allez travailler avec regex correspond directement et dans votre situation accidentelle particulière liée à l'invocation directe de méthodes sur
$!
.Cela m'a fait prendre conscience de la différence entre
Nil
etAny
, et la justification fournie était plus logique pour moi.la source
Nil
définit un conteneur à son état par défaut. Vous pouvez modifier la valeur par défaut.my $foo is default(42) = 5;
$foo = Nil;
say $foo; # 42