Iterating past the finish
A while ago the question was raised how to augment
Any
. As it turns out the augmenting part is working but the newly added method is not propagated to children of buildin types. One can force the propagation by calling .compose
on all type objects. Getting a list of all parents is done with .^mro
and the check is done with ∈
.
augment class Cool { method HTML { HTML.new(self) } }
if Cool ∈ T.HOW.mro(T) { T.HOW.compose(T); }
I stepped on a Dragon
The tricky part is to get all predefined classes. Mostly because there is a lot of stuff in CORE::
that doesn’t even implement the interfaces to call methods. We can call .DEFINITE
because that’s not a method. So we can weed out all predefined objects and are left with type objects and stuff that’s leaking from NQP into Perl 6-land. Those beasties don’t implement .mro
so by guarding with try
we can bild a list of all Perl 6 type objects. Those type objects contain IterationEnd
. Hence we can’t trust for
or anything else that is using iterators to loop over a list. There is also Slip
in the list. We can help that by using binding everywhere.
my @a = CORE::.values;
my @types;
for 0..^@a.elems -> $i {
my \T := @a[$i];
try @types[$++] := T if not T.DEFINITE;
}
for 0..^@types.elems -> $i {
my \T := @types[$i];
try if Cool ∈ T.HOW.mro(T) {
T.HOW.compose(T);
}
}
And there we have it. All children of Cool have been re-.composed
.
It’s no magic!
There are a few things I learned. Firstly much of the magic behind Perl 6 are just type checks. Anything that deals with iteration of lists or similar constructs is checking for Slip or IterationEnd and branching out to deal with their special nature.
And secondly there are a lot of interfaces leaking into spec-land that have no business there. I’m worried that might bite us later because any useful interface will be abused by programmers sooner or later. I would prefer the inner workings of Rakudo to be well hidden.
I found a way to deal with agumenting build in types so it can’t be long before the core devs fix that bug.