Skip Menu |

This queue is for tickets about the Moops CPAN distribution.

Report information
The Basics
Id: 90805
Status: resolved
Priority: 0/
Queue: Moops

People
Owner: Nobody in particular
Requestors: pdcawley [...] bofh.org.uk
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Strange compile errors when consuming Moops roles from Moose
Date: Mon, 25 Nov 2013 16:58:44 +0000
To: bug-Moops [...] rt.cpan.org
From: Piers Cawley <pdcawley [...] bofh.org.uk>
It turns out that consuming a Moops role from plain old Moose is surprisingly tricky. Suppose I have: use Moops; role Example using Moose { method foo { 'bar' } } then, when I write: perl -E 'package Consumer; use Moose; with 'Example'; package main; say Consumer->new->foo' compilation blows up complaining that I can only consume roles, and Example is not a moose role. However, when I do: perl -MExample -E '...' All is well. As it is when I do: perl -E 'use Example; package Consumer; ...' and even (this one surprised me) perl -E 'require Example; package Consumer; ...' But, if I do: perl -E 'package Consumer; use Example; ...' we're back to blowing up with the same error. I'm seeing this with perl 5.18.1, Moose 2.1005, Moops 0.26, Kavorka 0.019, Keyword::Simple 0.02, Module::Runtime 0.013 if that's of any use. Sorry this bug doesn't come with a .t file, but I couldn't work out how to write one to express the issues correctly.
Hmmm... You may want to add the following to the top of your Example.pm: package main; When Perl loads a module, if it doesn't explicitly start with a package statement, everything within is dumped into the currently compiling package. This means that the "Example" role is actually getting created as "Consumer::Example". I need to mention this in the docs.
Subject: Re: [rt.cpan.org #90805] Strange compile errors when consuming Moops roles from Moose
Date: Tue, 26 Nov 2013 10:00:15 +0000
To: bug-Moops [...] rt.cpan.org
From: Piers Cawley <pdcawley [...] bofh.org.uk>
Eek! That's kind of icky. Is there any way of making 'use Moops' force the package back to 'main'. Some sort of: use Moops -toplevel which one could use to tell Moops not to nest the package? Or (probably better) use lexical hints to manage auto nesting of Moops packages rather than dynamic scope because the current behaviour seems utterly... well, at the very least, surprising. On 25 November 2013 23:05, Toby Inkster via RT <bug-Moops@rt.cpan.org>wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=90805 > > > Hmmm... You may want to add the following to the top of your Example.pm: > > package main; > > When Perl loads a module, if it doesn't explicitly start with a package > statement, everything within is dumped into the currently compiling > package. This means that the "Example" role is actually getting created as > "Consumer::Example". > > I need to mention this in the docs. >
Unless there's a good reason not to, I'm trying to act similar to p5-mop, which in this case does the same thing. There have been a few people in the #p5-mop IRC channel similarly confused, so things may change in p5-mop, in which case Moops will probably change to match. Note that this issue only effects packages which contain no "::" in their names. You can add a leading "::" to work around it: use Moops; role ::Example using Moose { method foo { 'bar' } }
Moops now includes a test case along these lines... https://metacpan.org/source/TOBYINK/Moops-0.033/t/04composition.t Roles are now composed with the class at the *end* of the class declaration. So this: class Foo with Bar { method xyz { ... } } is roughly equivalent to: package Foo { use Moo; *xyz = sub { ... }; with "Bar"; } Sometimes, like if in your class you want to apply method modifiers to methods that were defined in your role, this order screws things up, but at least it's simple and understandable, and has an easy fix. The fix being to use `with` *inside* the class declaration instead of at the top.