TSa wrote:
Jonathan Lang wrote:
> TSa wrote:
>> This is exactly what I don't want. Such an equal method needs to be
>> written in each and every class the role GenPoint is composed into.
>
> No, it doesn't. It only needs to be written in those classes where
> the 'equal' method is supposed to behave differently than the one
> found in GenPoint.
Grumpf, yes. But I think that equality checking is something that needs
to deal with some class specific data. And hence the care-taking for
the role needs to be implemented many times while it could come out of
the composition process almost for free. I assume the class specific
part needs writing anyway.
OK; I think I see where you're coming from.
I don't think that the behaviour that you're describing should be Perl
6's default behavior; but I _could_ see implementing a sort of
"reverse delegation" trait that causes a role's class to start the
dispatch process for a given method with the role instead of the
class. Something like:
role GenPointMixin
{
is divert(:equal<GenPointMixin>);
has Int $.x;
has Int $.y;
method equal( ::?CLASS GenEqual $self: ::?CLASS $p --> Bool )
{
return $self.::?CLASS::equal($p) and $self.x == $p.x and
$self.y == $p.y;
}
}
Of course, you then run into a problem if the class _doesn't_ redefine
method equal; if it doesn't, then what is GenPointMixin::equal
calling? And you also run into a problem if you want the class to
track the position in polar coordinates instead of rectilinear ones -
it would still represent a point conceptually, but the implementation
of method equal (at least) would need to be overridden.
Or you could change the dispatch rules throughout the lexical scope
where the classes are defined with a 'use' statement; all's fair if
you predeclare, after all. But you'd still have the above issues.
A cleaner solution would be to define a private helper method which
the role then demands that the class override. This is _very_ similar
to the solution that you described as "clumsy" a few posts back, with
the main difference being that the helper method, being private, can't
be called outside of the class. To me, the only clumsiness of this
solution comes directly from the cluminess of the overall example, and
I consider your proposed alternative to be equally clumsy - it merely
trades one set of problems for another.
And yes, in Perl 6 the method isn't called equal but eqv or === and
has a default implementation that retrieves the .WHICH of both args.
What inspired that comment?
--
Jonathan "Dataweaver" Lang