The role must not be a class – that's true. Yet, have a look at my example with 
private methods. If accidentally two roles declare same private method – I 
either must reject using one of them or resolve the conflict manually... oh, 
wait, I have no idea of what is that private method is all about!

Another rare but not overall impossible pattern is when one would like to have 
a role method(s) be resolved with MRO. Something like:

    class Foo is A is B does R is C { ... }

where re-dispatching would be able to try resolving exactly in the specified 
order A -> B -> R -> C. Currently I see only two possible solutions:

- manual qualifiaction:
 
    self.?A::method; self.?B::method; self.?R::method; self.?C::method;

- Create an intermediate dummy class which would do R:

    class RClass does R { ... }
    class Foo is A is B is RClass is C { ... }

In the second case we would have do something with stubs in R because RClass 
would have to resolve them. And if this would require accessing private data on 
Foo then the latter would have to trust RClass:

    class Foo is A is B is RClass is C {
        trusts RClass;
    }

Doesn't it look somewhat clumsy??

Oh, and after all, we have submethods! And know what? If you have a submethod 
on a Role everything is fine until same name submethod would be required by the 
consuming class. In this case the class developer must know explicitly that he 
has to call role's submethod and how he has to do it if the submethod is called 
externally (similarly to BUILD/TWEAK been called at the construction stage). Or 
the calling code must know about the existence of ^roles method and use it.

I don't want roles to become classes. But I wish they'd have more privileges 
than they do now. BTW, it is even possible to have both approaches within same 
paradigm by having two ways of consuming roles: either through MRO or by mixing 
in. A developer could choose which one would do better in a particular 
situation.

> I'm not an expert on OO programming, but my understanding of roles is that 
> they make it possible to add some behaviors to a class (or to an object) 
> while avoiding some of  the pitfalls of inheritance, especially of multiple 
> inheritance. So, even though I know about punning, I would tend to argue that 
> roles are not classes (if they were, well, why would we need to have roles?. 
> In fact, I tend to think that they have been designed precisely not to be 
> classes and not to exhibit inheritance features, in order to avoid the 
> complex dependencies that sometimes arise with inheritance, especially 
> multiple inheritance and, more generally, complex inheritance trees. So, in 
> this view, roles should probably not need any MRO. If you need inheritance, 
> then probably use full-fledged classes. If you don't need inheritance, then, 
> possibly, roles may be better suited to what you need.
> 
> To me, classes are meant for managing instances and roles for managing 
> behaviors and code reuse.
> 
> Having said all that, I like to be able to compose some role(s) into another 
> role and I have done it a couple of times without encountering any problems, 
> as far as I can tell (but these were probably relatively simple cases). I 
> don't really see why this should be considered as an anti pattern, although I 
> can certainly feel that we should probably not try to ask too much from 
> roles, the aim after all is to have something simpler than a class.

Best regards,
Vadim Belman

Reply via email to