I know that it's way easier to ensure single instances from the class level, and that there's the excellent Staticish
module from Jonathan Stowe that does the same by using roles, but I just want to try and understand a bit better how the class higher order working can be handled, mainly for a FOSDEM talk. I could think of several ways of doing to at the metamodel level, but eventually this is what I came up with:
my class MetamodelX::Singleton is Metamodel::ClassHOW {
my \instance = Mu;
method compose(Mu \type) {
my &callsame := CORE::<&callsame>; # Workaround for RT #127858
self.method_table(type)<new>.wrap: -> \SELF, | {
unless instance.defined { instance = SELF };
callsame();
};
}
}
my package EXPORTHOW {
package DECLARE {
constant singleton = MetamodelX::Singleton;
}
}
Mainly ripped from the
OO::Monitors
code, written as far as I understand it, by JJ Atria and Jonathan Worthington)
Main rationale is trying to wrap the building submethod, or somehow whatever tries to create a new instance of the object. This, however (as well as the same with BUILD
and BUILDALL
, close to the original), fails with:
No such method 'wrap' for invocant of type 'Any'. Did you mean any of
these: 'Map', 'WHAT', 'grep', 'map'?
So quite clearly I'm not getting what these do, or for that matter the whole HOW concept. So any idea what might be failing here, or any other way to override the building of the object at the metamodel level to be able to do as intended?
bless
is the generation of one for the class when the rest of the class is composed. When the BUILDPLAN is created in github.com/rakudo/rakudo/blob/master/src/Perl6/Metamodel/…, it will not need to add that one, is that correct? – Garbers