How does one write custom accessor methods in Perl6?
If I have this class:
class Wizard {
has Int $.mana is rw;
}
I can do this:
my Wizard $gandalf .= new;
$gandalf.mana = 150;
Let's say I want to add a little check to a setter in my Perl6 class without giving up the $gandalf.mana = 150;
notation (in other words, I don't want to write this: $gandalf.setMana(150);
). The program should die, if it tries to set a negative mana. How do I do this? The Perl6 documentation just mentions it is possible to write custom accessors, but does not say how.
With more recent versions of Rakudo there is a subset named
UInt
that restricts it to positive values.So that you're not stuck in a lurch if you need to something like this; here is how that is defined:
( you can leave off the
my
, but I wanted to show you the actual line from the Rakudo source )You could also do this:
I would like to point out that the
* >= 0
in thewhere
constraint is just a short way to create a Callable.You could have any of the following as a
where
constraint:( If you wanted it to just not be zero you could also use
... where &prefix:<?>
which is probably better spelled as... where ?*
or... where * !== 0
)If you feel like being annoying to people using your code you could also do this.
If you want to make sure the value "makes sense" when looking at all of the values in the class in aggregate, you will have to go to a lot more work.
( It may require a lot more knowledge of the implementation as well )
You can get the same accessor interface that saying
$.mana
provides by declaring a methodis rw
. Then you can wrap a proxy around the underlying attribute like so:Proxy
is basically a way to intercept read and write calls to storage and do something other than the default behavior. As their capitalization suggests,FETCH
andSTORE
are called automatically by Perl to resolve expressions like$gandalf.mana = $gandalf.mana + 5
.There's a fuller discussion, including whether you should even attempt this, at PerlMonks. I would recommend against the above -- and public
rw
attributes in general. It's more a display of what it is possible to express in the language than a useful tool.