If I have a public method, I can call it inside its class using both $.name
and self.name
:
class TEST {
has Int $.a;
method b($x) {
return $!a * $x;
}
method c($y) {
return self.b($y) * 3; # or $.b($y)
}
}
my $m = TEST.new(a => 10);
say $m.c(2); # 60
But if I make b
a private method, I only can call it with self!b
, not $!b
, otherwise I get the following error message:
Attribute $!b not declared in class TEST
What's behind this rule? What are the rules of calling a method inside its own class?
An attribute can always be referred to as $!foo
in a class. If you do that, than the code will be generated to directly access the attribute itself, and any classes subclassing your class will not be able to change this behaviour.
If you use has $.foo
in the declaration of a class, it means that a public accessor (and if you add is rw
it can also function as a mutator).
When you use $.foo
in your code otherwise, it is exactly the same as $( self.foo )
. This means that it will call the method foo
on self
, and itemize the return value (make it a single "thing" if it wasn't yet). This will go wrong if you defined your attribute with $!foo
and you did not supply a method foo
yourself.
This goes even further: $.bar
really means self.bar
: you only need to have a method existing by the name bar
, which may not be related to any attribute at all.
If you define a private method !baz
, the !
just indicates the privacy of the method, which means you need to call it indeed as self!baz
. There is no short syntax for it.
Personally I dislike the fact that you can say $.zippo
even if zippo
is not an attribute. But I'm afraid that ship has sailed. But this behaviour is now causing you confusion :-(
So what's behind the rule for not having a short syntax for calling a private method? Not sure, I guess really that $!foo
was already taken to mean direct access to the attribute, and provide you with a compile time error if the attribute doesn't exist.
Hope this answers your question!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With