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

Reply via email to