Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using public and private methods inside their class in Perl 6

Tags:

raku

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?

like image 699
Eugene Barsky Avatar asked Apr 22 '18 20:04

Eugene Barsky


1 Answers

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!

like image 111
Elizabeth Mattijsen Avatar answered Sep 19 '22 18:09

Elizabeth Mattijsen