Sneaky methods
As one would expect methods can be declared and defined inside a class definition. Not so expected and even less documented are free floating methods declared with my method
. Now why would you want:
my method foo(SomeClass:D:){self}
The obvious answer is the Meta Object Protocols add_method-method, as can be found in Rakudo:
src/core/Bool.pm 32: Bool.^add_method('pred', my method pred() { Bool::False }); 33: Bool.^add_method('succ', my method succ() { Bool::True }); 35: Bool.^add_method('enums', my method enums() { self.^enum_values });
There is another, more sneaky use for such a method. You may want to have a look at what is going on in a chain of method calls. We could rip the expression apart and insert a one shot variable, do our debugging output, and continue in the chain. Good names are important and wasting them on one shot variables is unnecessary cognitive load.
<a b c>.&(my method ::(List:D){dd self; self}).say; # OUTPUT«("a", "b", "c")(a b c)»
We can’t have no name without an explicit invocant, because Perl 6 wont let us, so we use the empty scope ::
to make the parser happy. With a proper invocant, we would not need that. Also, the anonymous method is not a member of List. We need to use postfix .& to call it. If we need that method more then once we could pull it out and give it a name.
my multi method debug(List:D:){dd self; self}; <a b c>.&debug.say; # OUTPUT«("a", "b", "c")(a b c)»
Or we assign it as a default argument if we want to allow callbacks.
sub f(@l, :&debug = my method (List:D:){self}) { @l.&debug.say }; f <a b c>, debug => my method ::(List:D){dd self; self}; # OUTPUT«("a", "b", "c")(a b c)»
In Perl 6 pretty much everything is a class, including methods. If it’s a class it can be an object and we can sneak those in wherever we like.
-
July 25, 2016 at 23:192016.30 Fresh Rakudo Star! | Weekly changes in and around Perl 6