I spent considerable time debugging a script recently, and when I finally found the problem it was because of code that looked like this:
class Foo {
has $.bar;
method () {
# do stuff
$!.bar;
}
}
It turned out the problem was with that $!.bar
, which should have been either $!bar
or $.bar
. I get this.
But why doesn't this die?
Looking at this in more detail, it looks like the issue here is that I'm trying to call a (non-existent) method bar
on $!
, which at this point is Nil
because there haven't been any errors.
And it looks like I can actually call any method I want on Nil
and they all silently return Nil
, including stuff like Nil.this-is-a-fake-method
and Nil.reverse-entropy(123)
.
Is this a feature? If so, what's the rationale?
It's intended and documented, yes. The headline for Nil
is "Absence of a value or a benign failure", and the class documentation mentions
Any method call on
Nil
of a method that does not exist, and consequently, any subscripting operation, will succeed and returnNil
.say Nil.ITotallyJustMadeThisUp; # OUTPUT: «Nil» say (Nil)[100]; # OUTPUT: «Nil» say (Nil){100}; # OUTPUT: «Nil»
Synopsis 2 states "Any undefined method call on Nil
returns Nil
, so that Nil
propagates down method call chains. Likewise any subscripting operation on Nil
returns Nil
", so the intent seems to be allowing expressions like $foo.Bar()[0].Baz()
without requiring checks for Nil
at every step, or special "Nil-safe" method call and subscripting operators.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments