Stevan Little wrote:
Brad Bowman wrote:
> How does a Role require that the target class implement a method (or
> do another Role)?

IIRC, it simply needs to provide a method stub, like so:

method bar { ... }

This will tell the class composer that this method must be created
before everything is finished.


I suppose this is again where the different concepts of classes are
roles can get very sticky. I have always look at roles, once composed
into the class, as no longer needing to exist. In fact, if it weren't
for the idea of runtime role compostion and runtime role
introspection, I would say that roles themselves could be garbage
collected at the end of the compile time cycle.

Again, you've hit the nail on the head.  To elaborate on this a little
bit, the only reason that perl needs to keep track of a role hierarchy
at all is for parameter matching purposes (if Foo does Bar and Bar
does Baz, Foo can be used if a signature asks for Baz).

> I would like a way to make one Role to require that the target class
> "does" another abstract Role, is there already such a technique?

I am not familiar with one, but I have had this need as well lately in
using Moose roles. We have a concept in Moose (stolen from the
Fortress language) where a particular role can exclude the use of
another role, but not the ability to require it, although I see no
reason why it couldn't be done.

As I mentioned before, having role Bar require that Baz also be
composed is a simple matter of saying "role Bar does Baz".

This notion of exclusionary roles is an interesting one, though.  I'd
like to hear about what kinds of situations would find this notion
useful; but for the moment, I'll take your word that such situations
exist and go from there.

I wonder if it would be worthwhile to extend the syntax of roles so
that you could prepend a "no" on any declarative line, resulting in a
compilation error any time something composing that role attempts to
include the feature in question.  So, for instance, you might have

   role Bar {
       no method baz (Num, Str);

   class Foo does Bar {
       method baz (Num $n, Str $s) { ... } # compilation error: Bar
forbade this method!


   role Bar no does Baz { # granted, the english grammar is all wrong...

   class Foo does Bar does Baz { # compilation error: Bar forbade the
inclusion of Baz!

This is not the same as removing something that a composed role
brought in, which is a separate potentially useful notion.  The former
is "Foo doesn't play well with Bar; so don't try to use them
together"; the latter is "Foo can do _almost_ everything Bar can, but
not quite."  Mind you, if I ever see something to the effect of "Foo
does Bar except baz()" as valid syntax, I'll expect a query to the
effect of "Foo does Bar?" to answer to the negative.  This would
include "can Foo be used when Bar is asked for?"

Jonathan "Dataweaver" Lang

Reply via email to