Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

Ovid
  (email not shown publicly)
http://publius-ovidius.livejournal.com/
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Monday March 09, 2009
04:31 AM

Recursive Runtime Role Reapplication Really Rebounds

[ #38618 ]

An email I wrote to the Perl 6 language list.

(OK, the subject sucked, but I tried :)

From Synopsis 14, the Perl 6 Role Spec:

You can, however, say

$fido does Sentry;
$fido does Tricks;
$fido does TailChasing;
$fido does Scratch;

...

Unlike the compile-time role composition, each of these layers on a new mixin with a new level of inheritance, creating a new anonymous class for dear old Fido, so that a .chase method from TailChasing hides a .chase method from Sentry.

Recently I reported a bug in Moose's runtime role application. The bug was caused by repeated runtime role application causing recursive inheritance warnings. The problem was very hard to track down because I was effectively doing something like this:

$object->meta->apply('Some::Role') while 1;

(The reality is that we had a singleton with a role applied to it multiple times).

Eventually, the code broke and this was real fun to debug, but I can imagine a scenario for this being natural. Imagine that tour REST interface returns XML, but sometimes someone wants YAML. So you have:

$resultset does Role::Serializable::XML;

But sometimes:

$resultset does Role::Serializable::YAML;

Since you cache resultsets if they've not changed, you could easily have the XML and YAML roles getting reapplied at runtime multiple times.

I don't see anything in the spec addressing this. Aside from "don't do that", is this something which can be addressed in perl instead of Perl? This problem is closely related to the "ordering problem" with mixins and multiple inheritance that roles were designed to avoid!

I think this issue could be mitigated by allowing runtime role application to be lexically scoped:

{
    temp $resultset does Role::Serializable::YAML;
    print $resultset.as_string;
}

I think that would work, but I'm unsure.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • I really think that doing anything that is equivalent the following is an incorrect usage of the feature more then it is a bug.

    Some::Role->meta->apply($object) while 1;

    You can simply modify this line slightly and avoid all your warnings by doing this ...

    while (1) {
        Some::Role->meta->apply($object) unless $object->does('Some::Role');
    }

    Sure it would be nice if Moose prevented you from shooting yourself in the foot like this, but what if you really wanted to shoot yourself i

    • I do see your point and I think you're right (I've some issues with implementation, but that's OK :). At the very least, though, I would like to see Moose::Role be able to generate a sane error message to make it easier to track bugs like this down.

      • The problem is that we are not considering it an error. The particular errors you were getting were tricky not because of something Moose::Role did as much as your repeated application of the role to the class caused really odd side effects to happen. How would I tell the difference between a error borne from side-effects and one that I could directly trace back to a mis-use of the feature?

        - Stevan

        • I'm not saying that Moose::Role is behaving in error here. I'm saying there's a detectable error condition and a better error message would help.

          How would I tell the difference between a error borne from side-effects and one that I could directly trace back to a mis-use of the feature?

          When applying a role at runtime, by noting Perl's recursive inheritance limit (98 role applications on my Solaris box) and issuing a reasonable error reporting the package/file/line number of role application, it would have been trivial for me to find the source error. Currently this error wins my personal "most obscure error message" award :)

          Deep recursion on s

          • Okay, I will agree that is could be detected, but how simple it is to do is another thing entirely. You are always invited to fork the Moose git repo and patch this if you like.

            - Stevan