Ovid wrote:
Having a problem with the following role in Perl 5:
package PIPs::ResultSource::Role::HasTags;
use Moose::Role;
requires 'do_setup';
after 'do_setup' => sub { ... };
So far this has worked really well, aside from that one class which didn't call
'do_setup'. Oops.
Requiring methods and requiring methods to be called are different things. It might be a
nice feature to have roles which tie into "events". If a particular condition
doesn't hold true by, say, INIT time, the role fails.
How would I implement something like that in Perl 6? Or am I just looking at
this wrong?
Well, if class composition time is OK and you want to decide whether the
role composes or not, then you can always write a where block in a
parametric role. Example from Rakudo (excuse the crap error message):
> role MaybeComposes[$x where { $*thingy == 42 }] { }
> class Foo does MaybeComposes['worreva'] { }
Use of uninitialized value
No applicable candidates found to dispatch to for '_block20'
> $*thingy = 42;
> class Bar does MaybeComposes['worreva'] { }
>
Just relies on normal dispatch-y stuff when picking the role. Means you
gotta pass a parameter of course... Note you can also provide a
fall-back role to compose by having one differently constrained. ;-)
I kinda wonder that since I believe roles are all implicitly are
parametrized on $?CLASS (didn't quite get to making that so yet in
Rakudo...or clear in S14 ;-)) if you would write:
role Foo[$?CLASS where { $*thingy == 42 }: ] { }
Note the :. You are just taking the invocant into $?CLASS as normal
(though it may get it anyway), but then adding a constraint on that.
Hmm...neater maybe. And if $?CLASS always gets the invocant anyway, like
self in methods, regardless of if you stick if somewhere else too, then
maybe even:
role Foo[$ where { $*thingy == 42 }: ] { }
Is permissible (but STD.pm doesn't like any of this role signature
invocant stuff at the moment).
Jonathan