On Fri, Dec 19, 2003 at 10:36:01AM -0600, Adam D. Lopresto wrote: : I've been trying to follow the recent discussion on roles and properties and : traits and such, but there's something that bugs me. If I understand : correctly, adding a role at runtime using but won't override any methods : defined by the class itself (but it will override inherited methods). But then : if I create a class that has its own method of saying whether it's true or not, : does that mean that "but true" and "but false" won't do anything to it? : : class Complex { : has $.real; : has $.imag; : : ... : : #Actually, how do we define this? : method asBoolean(Complex $self:){ : return $self.real || $self.imag; : } : : : ... : : : then somewhere in a function : : return Complex::new(0,0) but true; : : Since Complex already has an implementation of whatever method decides whether : it's true or not, wouldn't just applying a property be insufficient to override : that?
That is a problem, and you'll notice I haven't answered Jonathan Lang yet. That's because I've been thinking about this issue all week, and I haven't thought of a way around the problem. Which probably means that C<but> really does imply the derivation of a new class somehow. Which in turn implies that C<but> is probably not powerful enough yet, because it might not only bind roles, but also new class methods to control those roles. Maybe $x but bar is just shorthand for something like: $x but class AnonClass is classof($x) does FooBar[bar] { } (presuming that bar is an enum of type FooBar). But it's not clear in that case how you go about caching identical anonymous classes. Well, okay, all you have to do is memoize the metaclass's class generator, but still... Maybe there's an intermediate syntactic form like: $x but subclass MyClass does FooBar[bar] { } Or maybe the long form is just class AnonClass is classof($x) does FooBar[bar] { }.bless($x) except that actually putting a run-time $x into a compile-time declaration is a bit of a problem, and it'd be nice to get rid of the redundant $x. (Plus .bless is maybe gonna try and do things we don't want done to $x.) On the other hand, if "bar" is some kind of BUILD argument rather than a subtype, maybe it's class AnonClass is classof($x) does FooBar { }.bless($x, foobar => bar) Maybe with a lazy "isa" applied by subclass's .bless we can reduce that to: subclass does FooBar { }.bless($x, foobar => bar) However we write it, this derivation does do something more like a "slatheron" with respect to the original class. However, a single such "slather" can apply multiple roles as well as new class methods. So all the compositional power of roles is still there within that new class. I guess the real power of roles comes from their parallel composition into a class, not from being able to apply them one by one at run time. So what we need to do is make C<but> apply a new class containing some number of collected and rationalized roles (usually one). Call it controlled slathering...it lets you use inheritance for slathering as it should be, while not forcing you to use extra levels of inheritance to mix in multiple roles when you should instead be using a composition. I think I'm happier with that. $rubyometer += 0.3 or so. :-) Larry