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

Reply via email to