I can call any method on Nil and this feels wrong

jja :

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?

hobbs :

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 return Nil.

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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=29382&siteId=1