Passei um tempo considerável depurando um script recentemente e, quando finalmente encontrei o problema, foi por causa do código que se parecia com isso:
class Foo {
has $.bar;
method () {
# do stuff
$!.bar;
}
}
Acabou que o problema era com isso $!.bar
, que deveria ter sido um $!bar
ou outro $.bar
. Eu entendi isso.
Mas por que isso não morre ?
Olhando para isso com mais detalhes, parece que a questão aqui é que eu estou tentando chamar um método (inexistente) bar
em $!
, que neste momento é Nil
porque não houve nenhum erro.
E parece que eu posso realmente chamar qualquer método que eu queira Nil
e todos eles retornam silenciosamente Nil
, incluindo coisas como Nil.this-is-a-fake-method
e Nil.reverse-entropy(123)
.
Isso é um recurso? Se sim, qual é a lógica?
Nil
retornosNil
, para queNil
propaga cadeias de chamadas de método." Portanto, pretende-se que você possa fazer isso$foo.Bar().Baz().Blah()
sem precisar de testes nulos a cada etapa ou de um?.
tipo especial de operador (desde que você lide corretamente com nil no final). Vou editar isso, obrigado.Nil
que não erra e apenas retrocede mais,Nil
recebe um uso bastante extenso no Obj-C e nos NS Frameworks, onde é usado de maneira semelhante - permite chamadas em cadeia que continuam passando Nil. Não conheço as penalidades exatas de desempenho das exceções e as apanhamos, mas meu palpite é que oNil
encadeamento pode ser mais eficiente, se menos flexível.Nil
classe possui um métodoFALLBACK
docs.raku.org/language/typesystem#index-entry-FALLBACK_(method) , que retornaNil
. Basicamente, pouco antes de uma exceção ser lançada porque um método não pôde ser encontrado, uma verificaçãoFALLBACK
é feita e chamada se disponível.Essa pergunta (e a resposta de hobbs) também me deixou desconfortável: acabei encontrando https://docs.raku.org/language/traps : explica que atribuir
Nil
geralmente produz um valor diferenteAny
. A seguinte interação básica do REPL também demonstra isso:((a diferença entre
=
e:=
é abordada aqui: https://docs.raku.org/language/containers#Binding ))... então a ideia geral é que o 'valor ausente ou falha benigna' é muito menos difundido no código regular do que eu (e talvez você também?) subitamente temia: ocorre no entanto, quando você trabalha com regex corresponde diretamente e em sua situação acidental específica relacionada à chamada direta de métodos em
$!
.Isso me deixou mais consciente da diferença entre
Nil
eAny
, e a lógica fornecida fazia mais sentido para mim.fonte
Nil
define um contêiner para seu estado padrão. Você pode alterar o valor padrão.my $foo is default(42) = 5;
$foo = Nil;
say $foo; # 42