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/