Pasé un tiempo considerable depurando un script recientemente, y cuando finalmente encontré el problema fue por un código que se veía así:
class Foo {
has $.bar;
method () {
# do stuff
$!.bar;
}
}
Resultó que el problema era con eso $!.bar
, que debería haber sido $!bar
o $.bar
. Entiendo esto.
¿ Pero por qué no muere esto ?
En cuanto a esto con más detalle, parece que el problema aquí es que estoy tratando de llamar a un método (inexistente) bar
de $!
que en este momento es Nil
porque no ha habido ningún error.
Y parece que realmente puedo llamar a cualquier método que quiera Nil
y todos regresan en silencio Nil
, incluyendo cosas como Nil.this-is-a-fake-method
y Nil.reverse-entropy(123)
.
¿Es esta una característica? Si es así, ¿cuál es la razón?
Nil
devolucionesNil
, de modo queNil
propaga cadenas de llamadas de método". Por lo tanto, está destinado a que pueda hacerlo$foo.Bar().Baz().Blah()
sin necesidad de pruebas nulas en cada paso o un?.
tipo especial de operador (siempre que maneje correctamente nil al final). Lo editaré en, gracias.Nil
que no produce errores y solo arroja más,Nil
obtiene un uso bastante extenso en Obj-C y NS Frameworks, donde se usa de manera similar: permite llamadas encadenadas que continúan pasando a Nil. No sé las penalizaciones de rendimiento exactas de las excepciones y la captura, pero supongo que elNil
encadenamiento puede ser más eficiente, aunque menos flexible.Nil
clase tiene un métodoFALLBACK
docs.raku.org/language/typesystem#index-entry-FALLBACK_(method) , que devuelveNil
. Básicamente, justo antes de que se produzca una excepción porque no se pudo encontrar un método, se realiza una verificaciónFALLBACK
y se llama si está disponible.Esta pregunta (y la respuesta de hobbs) también me hizo sentir ... incómodo: finalmente encontré https://docs.raku.org/language/traps : explica que la asignación
Nil
produce un valor diferente, por lo generalAny
. La siguiente interacción básica REPL también demuestra esto:((la diferencia entre
=
y:=
se cubre aquí: https://docs.raku.org/language/containers#Binding ))... así que la idea general es que el 'valor ausente o falla benigna' está mucho menos extendido en el código regular de lo que yo (¿y quizás usted también?) de repente temía: sin embargo, ocurre cuando va a trabajar con expresiones regulares coincide directamente y en su situación accidental particular relacionada con la invocación directa de métodos
$!
.Esto me hizo más consciente de la diferencia entre
Nil
yAny
, y la justificación proporcionada tenía más sentido para mí.fuente
Nil
establece un contenedor a su estado predeterminado. Puede cambiar el valor predeterminado.my $foo is default(42) = 5;
$foo = Nil;
say $foo; # 42