Re: test case for trouble inheriting overload behavior with roles

[email protected] (Stevan Little)
Newsgroups perl.moose
Message-ID <[email protected]>
Hello,

On Aug 21, 2007, at 12:29 PM, John Napiorkowski wrote:
> Hi,
>
> Recently I was building a Role that used the overload
> module to manage some simple stringify behavior when I
> noticed that classes which consumed the role didn't
> seem to get the overload behavior.

Yes, roles do not currently support overload.

> Basically the test case shows how overload works for
> inheritance with plain old perl objects, moose
> objects, but not for moose objects which do a role.
>
> I'm guessing that this would be an issue for other
> modules that work similarly to overload, in that they
> create stuff in import that is on the caller
> namespace.  So this problem might bite others at weird
> times.

Yes, that is correct. Class::MOP (the underlying meta-object layer  
that Moose sits on) does not consider a method part of a class unless  
the CV (code reference) declares that it is from that package.  
Class::MOP uses the Sub::Name module to insure that this is true, but  
normal perl import behavior does not do this.

In most cases this is not an issue, since this type of "mixin"  
behavior is widely known as a hack and is usually only used in  
limited cases (for instance CGI::Application uses this in their  
"Plugin" mechanism). In addition, the whole idea of roles is what is  
meant to replace this hack, so the collision of these things is even  
more unlikely.

Now, this is only partially the problem with roles and overload.

> If anyone more familiar with how Roles do their job
> could take a look at the test case and let me know
> what they think I would appreciate it.

The way roles work is to collect all the methods in the package, and  
then (using a strict set of method combination and conflict rules)  
stuff these methods into the class (or role) which is consuming it.  
The presents some difficulties for overload, the first being the fact  
that the (CV) methods imported by overload do not appear to come from  
the role package. The second issue being that overload does some  
other tricks under the covers, in particular it uses a method named  
"()" (yes, that is the actual name of the method) to mark that a  
package is using overloading. Because this method is only used  
internally by overload, a role should not treat this as a method  
conflict if it were to see the method multiple times. However, that  
is exactly how it would interpret it. There were some other issues,  
but I don't recall what they were. I found all this out the hard way  
when I first wrote Class::Trait.

So, to make a long story short, overload support cannot be done  
"automatically" with roles, given to the nature of how overload.pm  
itself is implemented. With Class::Trait I added an $overload  
variable, which stored the args for overload::import, and then  
applied them to each package. This (or something similar) could  
certainly be done with roles. Of course it would require that the  
overloaded methods also go through the same composition/conflict  
rules that methods go through, and we would also need to capture  
"required" overloads as well in order to properly support all  
functionality. So it's fairly straightforward, but the implimentation  
is non-trivial.

> I'm happy to work on this as well, just need a little
> mentoring about where to start.

I would be happy to point you in the right direction, but right now  
the role mechanism is getting a long needed refactoring. I suggest  
you wait until after that is complete (hopefully in the next month or  
so) before you try to add this feature. It will be well worth the  
wait since you should then be able to re-use the compsition/conflict  
mechanism instead of re-writing it (as you would have to do now).

- Stevan
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.