Joseph Ryan wrote:

> Of course, roles are another great way to prevent confusion with
> multiple inheritance.  A good question would be whether something
> like "forget" is useful in addition, or whether everyone should
> just use roles. :)

For the record, roles are not a form of multiple inheritence.  They're
similar in that both are techniques for code re-use; but there are crucial
differences - for instance, classes call methods; roles merely provide
methods for classes to call.  

How about this: allow for two approaches for calling a given method:
implicit (state the object and the method, and leave it up to the class
dispatcher to figure out where the method is to be found - in the class,
one of its roles, or one of its parents) or explicit (state the object,
the method, and the class or role where it will be found).  Allow
exclusion of inherited and role methods, but define exclusion strictly in
terms of implicit calls: you're telling the class dispatcher to ignore
that role or parent when searching for candidate methods to call.  

Explicit calls would suffer from "brittleness" - that is, if you rename a
role or a class, you'd need to hunt down every instance where one of its
methods is explicitly called and rename it there as well.  Implicit calls,
OTOH, would risk incompleteness - exclude an inherited or role method from
a class without providing a valid substitute, and other code may end up
assuming that the class has capabilities that it doesn't.  

The danger isn't really in the ability to suppress a method from a given
role or parent; the danger comes from the ability to suppress a method
from _every_ role or parent.  A safe alternative to this would be to
define a class method which then turns around and explicitly calls the
inherited or role method that you really wanted; the drawback here is the
poor Huffman encoding involved: writing a method is considerably more
bulky than saying "exclude ..." or "rename ...".  You can resolve this
dilemma in two ways (not mutually exclusive): forbid the latter options,
or come up with a more succinct way of handling the former option.  

OK; add a trait for methods: call it "from", and require it to take one
parameter: the name of a role or parent.  What it does is to automatically
redirect any calls to that method, while removing the need for a code
block.  So:

  class Parent {
    method foo () {...}
  }
  
  class Role {
    method foo () {...}
  }
  
  class Bar is Parent does Role {
    method foo () is from Parent;
  }

C<is from Parent> would be equivelent to C<{return Parent::foo();}>.  

=====
Jonathan "Dataweaver" Lang

__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free web site building tool. Try it!
http://webhosting.yahoo.com/ps/sb/

Reply via email to