The excellent 2011 Advent of Raku post Meta-programming: what, why and how provides a few clear examples of using EXPORTHOW
to create a declarator that acts like class
. Here's the first:
my class SingleInheritanceClassHOW
is Metamodel::ClassHOW
{
method add_parent(Mu $obj, Mu $parent) {
if +self.parents($obj, :local) > 0 {
die "Multiple inheritance is forbidden!";
}
callsame;
}
}
my module EXPORTHOW { }
EXPORTHOW.WHO.<class> = SingleInheritanceClassHOW;
Is there a way to do something similar for a declarator that acts like sub
(that is, that allows the use to supply a signature and block, rather than allowing the user to supply attributes and methods)? The metaclass of a Sub
is ClassHOW
, so it seems that something similar should be possible, but I'm not seeing a way to do so.
The EXPORTHOW
mechanism is only for overriding the metaclass that will be used for package declarators, with the slight extension that EXPORTHOW::DECLARE
also performs a grammar tweak that introduces a new package declarator.
While one can call .HOW
on a Sub
, the result does not relate to the subroutine itself, but rather the metaclass of the Sub
type, of which a subroutine is an instance.
Really, EXPORTHOW
is an "easy things easy" mechanism (to the degree it's fair to call anything relating to meta-programming easy!) It was also a straightforward thing to provide: the parsing of package declarations was already extremely regular, and the compiler already maintained a mapping table from package keyword to metaclass, so providing a way for a module to replace entries in that table (or add new ones for DECLARE
) was barely a few hours of compiler hackery.
Routines are vastly less regular, even if that's only somewhat apparent syntactically. While packages pretty much parse the keyword (class
, role
, grammar
, etc.) and what follows is the very same syntax and semantics for all of them (modulo roles permitting a signature), there are separate parse rules and semantics behind each of sub
, method
, macro
, and rule
. Their interaction with the overall compilation process is also rather more involved. The ongoing RakuAST effort is bringing a bit more order to that chaos, and ultimately - when coupled with slangs - will offer a way to introduce new sub
-like constructs, as well as to give them semantics.