Open Xliff opened 1 year ago
My recollection is that a COMPOSE
phaswer was once proposed, but it was realized that this is also the time at which the role
body runs, and so the functionality it would provide already exists.
My recollection is that a
COMPOSE
phaser was once proposed, but it was realized that this is also the time at which therole
body runs, and so the functionality it would provide already exists.
Indeed, the COMPOSE
phaser is still documented. TIL though that the role body runs at that composition time. We should document this, I feel like I've had an instance or two where it would have been useful.
I wonder if the COMPOSE
phaser may have been initially thought to provide some other access, e.g., sub COMPOSE($type) { ... }
. That would be the only advantage over the body which afaict is ignorant of the type it's being composed into. But that might also be a breaking of OO principles too, so perhaps not the best idea.
That would be the only advantage over the body which afaict is ignorant of the type it's being composed into.
The target class is in ::?CLASS
:
$ raku -e 'role R { say qq[Composing into {::?CLASS.^name}] }; class C does R {}'
Composing into C
I'm not currently ready to clearly recall what was the context, but there is actually another stage, where COMPOSE
can be considered useful. I think, it was about conretization composition time. Correspondingly, the phaser was supposed to be invoked on the concretization itself.
BTW, for 6.e a submethod COMPOSE
can be used for this purpose. And this is something that can be done right away. Moreover, the submethod can be utilized for this purpose for classes and parametric roles too, if considered useful. Akin to BUILD
/TWEAK
but at type object level.
Here's a situation where the role body does NOT fire:
role R {
say qq[Composing into { ::?CLASS.^name }];
}
class A does R {}; # Fires
class B {};
my $b = B.new but R; # Fires
my $c = B.new;
$c does R; # Does NOT fire
That's because the type B+{R}
has been created already by my $b = B.new but R
, so no new type needs to be created for $c does R
, and so the role body does not get run.
If you swap them around, you'll see that it does fire on the does
if it's the first one.
my $c = B.new;
$c does R; # Fires
my $b = B.new but R; # Does NOT fire
That's because the type
B+{R}
has been created already bymy $b = B.new but R
Let me add to this that would there be a phaser it wouldn't fire either.
I see. Thanks for the explanation, @lizmat
BTW, forgot to mention here that I have an experimental solution for COMPOSE
submethod in rakudo/rakudo#5312
Is COMPOSE
the non-Grammar equivalent of make
/made
?
This is a phaser that can be added for roles that will fire whenever said role is composed on an object either at class composition time "via class A does R" or at runtime via "my $a = A.new but R".
Having such a feature could go a long way into solving some problems.
Method::Also
is one module that would benefit from such.