Skip Menu |

This queue is for tickets about the Moose CPAN distribution.

Report information
The Basics
Id: 117159
Status: rejected
Priority: 0/
Queue: Moose

People
Owner: Nobody in particular
Requestors: toby [...] inf.ed.ac.uk
Cc:
AdminCc:

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



Subject: problem with role trait which consumes another role trait
Date: Tue, 23 Aug 2016 10:45:17 +0100 (BST)
To: bug-Moose [...] rt.cpan.org
From: Toby Blake <toby [...] inf.ed.ac.uk>
Hi, I *think* this is a bug in Moose, or more likely, Moose::Exporter. I posted a message similar to this, to the Moose mailing list (just in case this looks familiar)... We have a bit of code which has broken between 2.1005 and 2.1804 - it was originally written somewhere around 0.85 and I don't think has really changed much since then. The code involves a role trait which consumes another role trait, and this seems to be what's causing the problem. Hopefully some simple code will explain this... package Test::Meta::Role::Trait::Trait1; use Moose::Role; Moose::Exporter->setup_import_methods( with_meta => [ 'trait1sub' ], also => 'Moose::Role', ); sub trait1sub { my $meta = shift; print "trait1sub\n"; } no Moose::Role; package Moose::Meta::Role::Custom::Trait::Trait1; sub register_implementation {'Test::Meta::Role::Trait::Trait1'}; 1; package Test::Meta::Role::Trait::Trait2; use Moose::Role; with 'Test::Meta::Role::Trait::Trait1'; Moose::Exporter->setup_import_methods( with_meta => [ 'trait2sub', 'trait1sub' ], also => 'Moose::Role', ); sub trait2sub { my $meta = shift; print "trait2sub\n"; } no Moose::Role; package Moose::Meta::Role::Custom::Trait::Trait2; sub register_implementation {'Test::Meta::Role::Trait::Trait2'}; 1; package Test::TestRole; use Test::Meta::Role::Trait::Trait2; use Moose::Role -traits => 'Trait2'; trait1sub; trait2sub; no Moose::Role; 1; This works fine with moose-2.1005: [mambo]toby: perl -Ilib -MTest::TestRole trait1sub trait2sub ^C [mambo]toby: ... but not with moose-2.1804: [bolt]toby: perl -Ilib -MTest::TestRole Bareword "trait2sub" not allowed while "strict subs" in use at lib/Test/TestRole.pm line 7. Compilation failed in require. BEGIN failed--compilation aborted. [bolt]toby: Thanks, Toby Blake School of Informatics University of Edinburgh -- The University of Edinburgh is a charitable body, registered in Scotland, with registration number SC005336.
On Tue Aug 23 05:45:43 2016, toby@inf.ed.ac.uk wrote: Show quoted text
> Hi, > > I *think* this is a bug in Moose, or more likely, Moose::Exporter. > > I posted a message similar to this, to the Moose mailing list (just in > case this looks familiar)... > > We have a bit of code which has broken between 2.1005 and 2.1804 - it > was originally written somewhere around 0.85 and I don't think has > really changed much since then. > > The code involves a role trait which consumes another role trait, and > this seems to be what's causing the problem. Hopefully some > simple code will explain this... > > > package Test::Meta::Role::Trait::Trait1; > > use Moose::Role; > > Moose::Exporter->setup_import_methods( > with_meta => [ 'trait1sub' ], > also => 'Moose::Role', > ); > > sub trait1sub { > my $meta = shift; > print "trait1sub\n"; > } > > no Moose::Role; > > package Moose::Meta::Role::Custom::Trait::Trait1; > sub register_implementation > {'Test::Meta::Role::Trait::Trait1'}; > > 1; > > > package Test::Meta::Role::Trait::Trait2; > > use Moose::Role; > with 'Test::Meta::Role::Trait::Trait1'; > > Moose::Exporter->setup_import_methods( > with_meta => [ 'trait2sub', 'trait1sub' ], > also => 'Moose::Role', > ); > > sub trait2sub { > my $meta = shift; > print "trait2sub\n"; > } > > no Moose::Role; > > package Moose::Meta::Role::Custom::Trait::Trait2; > sub register_implementation > {'Test::Meta::Role::Trait::Trait2'}; > > 1; > > > package Test::TestRole; > use Test::Meta::Role::Trait::Trait2; > > use Moose::Role -traits => 'Trait2'; > > trait1sub; > trait2sub; > > no Moose::Role; > 1; > > > This works fine with moose-2.1005: > > [mambo]toby: perl -Ilib -MTest::TestRole > trait1sub > trait2sub > ^C > [mambo]toby: > > > ... but not with moose-2.1804: > > [bolt]toby: perl -Ilib -MTest::TestRole > Bareword "trait2sub" not allowed while "strict subs" in use at > lib/Test/TestRole.pm line 7. > Compilation failed in require. > BEGIN failed--compilation aborted. > [bolt]toby:
I'm not totally sure if I'm following, but it looks like you expect the application of a trait to _also_ export anything provided by that trait. I don't think this was ever an _intentional_ behavior in Moose::Exporter (at least not the parts I wrote). Moose::Exporter is there to let you write modules that act like Moose _when you directly import them_. It's hard for me to imagine how this ever could have worked, but Moose::Exporter is some complex code. I certainly don't think this behavior would be a desired feature, since it seems awfully surprising that simply applying a trait would also import some subs. FWIW, nothing jumps out for me in a diff of Moose::Exporter from 2.1005 to HEAD . Regardless, I suggest you separate the "is a trait" code from the "exports a meta-wrapping sub" code into separate packages: package MyRole; use Moose::Role -traits => 'Foo'; use Foo::ExportsSomething; Cheers, -dave
CC: Toby Blake <toby [...] inf.ed.ac.uk>
Subject: Re: [rt.cpan.org #117159] problem with role trait which consumes another role trait
Date: Tue, 13 Sep 2016 14:26:50 +0100
To: bug-Moose [...] rt.cpan.org
From: Toby Blake <toby [...] inf.ed.ac.uk>
Show quoted text
> On 11 Sep 2016, at 05:43, Dave Rolsky via RT <bug-Moose@rt.cpan.org> wrote: > > <URL: https://rt.cpan.org/Ticket/Display.html?id=117159 > > > I'm not totally sure if I'm following, but it looks like you expect the application of a trait to _also_ export anything provided by that trait. I don't think this was ever an _intentional_ behavior in Moose::Exporter (at least not the parts I wrote). Moose::Exporter is there to let you write modules that act like Moose _when you directly import them_. > > It's hard for me to imagine how this ever could have worked, but Moose::Exporter is some complex code. I certainly don't think this behavior would be a desired feature, since it seems awfully surprising that simply applying a trait would also import some subs. FWIW, nothing jumps out for me in a diff of Moose::Exporter from 2.1005 to HEAD . > > Regardless, I suggest you separate the "is a trait" code from the "exports a meta-wrapping sub" code into separate packages: > > package MyRole; > > use Moose::Role -traits => 'Foo'; > > use Foo::ExportsSomething;
Hi Dave, Thanks for your reply. The intention behind the original code is so we can do something like this... Trait1 exports some subs using Moose::Exporter Trait2 consumes Trait1 and also exports (different) subs using Moose::Exporter So, then we could do... use Moose::Role -traits => 'Trait1'; (and use the subs which Trait1 exports) ...or ... use Moose::Role -traits => 'Trait2'; (and use the subs that _both_ Trait1 and Trait2 export) This used to work, but am I right in saying that you think this only ever worked unintentionally? I can try and rework code along the lines you suggest, but I note I can't seem to use more than one trait which use Moose::Exporter... package Test::Meta::Role::Trait::Trait1; use Moose::Role; Moose::Exporter->setup_import_methods( with_meta => [ 'trait1sub' ], also => 'Moose::Role', ); sub trait1sub { my $meta = shift; print "trait1sub\n"; } no Moose::Role; package Moose::Meta::Role::Custom::Trait::Trait1; sub register_implementation {'Test::Meta::Role::Trait::Trait1'}; 1; package Test::Meta::Role::Trait::Trait2; use Moose::Role; Moose::Exporter->setup_import_methods( with_meta => [ 'trait2sub' ], also => 'Moose::Role', ); sub trait2sub { my $meta = shift; print "trait2sub\n"; } no Moose::Role; package Moose::Meta::Role::Custom::Trait::Trait2; sub register_implementation {'Test::Meta::Role::Trait::Trait2'}; 1; package Test::TestRole; use Test::Meta::Role::Trait::Trait1; use Test::Meta::Role::Trait::Trait2; use Moose::Role -traits => [ 'Trait1', 'Trait2' ]; no Moose::Role; 1; On 2.1005: [mambo]toby: perl -Ilib -MTest::TestRole ^C [mambo]toby: On 2.1804: [bolt]toby: perl -Ilib -MTest::TestRole Due to method name conflicts in roles 'Test::Meta::Role::Trait::Trait1' and 'Test::Meta::Role::Trait::Trait2', the methods 'import' and 'unimport' must be implemented or excluded by 'Moose::Meta::Class::__ANON__::SERIAL::1' at /usr/lib64/perl5/vendor_perl/Moose/Exporter.pm line 510 Moose::Role::import('Moose::Role') called at lib/Test/TestRole.pm line 5 Test::TestRole::BEGIN at lib/Test/TestRole.pm line 5 eval {...} at lib/Test/TestRole.pm line 5 require Test/TestRole.pm at - line 0 main::BEGIN at lib/Test/TestRole.pm line 5 eval {...} at lib/Test/TestRole.pm line 5 BEGIN failed--compilation aborted at lib/Test/TestRole.pm line 5. Compilation failed in require. BEGIN failed--compilation aborted. [bolt]toby: Perhaps I'm misunderstanding the intended usage of Moose::Exporter? I didn't write the code in question, just inherited it. Thanks again for your input into this. Cheers Toby -- The University of Edinburgh is a charitable body, registered in Scotland, with registration number SC005336.
On 2016-09-13 08:26:31, toby@inf.ed.ac.uk wrote: Show quoted text
> Thanks for your reply. The intention behind the original code is so > we can do something like this... > > Trait1 exports some subs using Moose::Exporter > Trait2 consumes Trait1 and also exports (different) subs using > Moose::Exporter > > So, then we could do... > > use Moose::Role -traits => 'Trait1'; > > (and use the subs which Trait1 exports) > > ...or ... > > use Moose::Role -traits => 'Trait2'; > > (and use the subs that _both_ Trait1 and Trait2 export) > > This used to work, but am I right in saying that you think this only > ever worked unintentionally?
AFAIK, this was never an intended part of the design. Applying traits is just supposed to affect the metaclass. What _is_ supposed to work is something like this: package Foo; use Moose::Role; use MooseX::Trait2; In this scenario the MooseX::Trait2 package could both alter the metaclass and export subs. This is what MooseX::Exporter is explicitly designed to do. But passing "-traits" was never supposed to be equivalent to a "use" (again, AFAIK). Show quoted text
> I can try and rework code along the lines you suggest, but I note I > can't seem to use more than one trait which use Moose::Exporter... > > package Test::Meta::Role::Trait::Trait1; > > use Moose::Role; > > Moose::Exporter->setup_import_methods( > with_meta => [ 'trait1sub' ], > also => 'Moose::Role', > ); > > sub trait1sub { > my $meta = shift; > print "trait1sub\n"; > } > > no Moose::Role; > > package Moose::Meta::Role::Custom::Trait::Trait1; > sub register_implementation > {'Test::Meta::Role::Trait::Trait1'}; > > 1; > > > package Test::Meta::Role::Trait::Trait2; > > use Moose::Role; > > Moose::Exporter->setup_import_methods( > with_meta => [ 'trait2sub' ], > also => 'Moose::Role', > ); > > sub trait2sub { > my $meta = shift; > print "trait2sub\n"; > } > > no Moose::Role; > > package Moose::Meta::Role::Custom::Trait::Trait2; > sub register_implementation > {'Test::Meta::Role::Trait::Trait2'}; > > 1; > > > package Test::TestRole; > use Test::Meta::Role::Trait::Trait1; > use Test::Meta::Role::Trait::Trait2; > > use Moose::Role -traits => [ 'Trait1', 'Trait2' ]; > > no Moose::Role; > 1;
See above for my suggestion. Instead of passing "-traits" just use the various extensions in the Test::TestRole package. Cheers, -dave
Subject: Re: [rt.cpan.org #117159] problem with role trait which consumes another role trait
Date: Fri, 16 Sep 2016 17:11:07 +0100
To: bug-Moose [...] rt.cpan.org
From: Toby Blake <toby [...] inf.ed.ac.uk>
Show quoted text
> On 16 Sep 2016, at 17:07, Dave Rolsky via RT <bug-Moose@rt.cpan.org> wrote: > > <URL: https://rt.cpan.org/Ticket/Display.html?id=117159 > >
[...] Show quoted text
> See above for my suggestion. Instead of passing "-traits" just use the various > extensions in the Test::TestRole package.
OK, will do, thanks for clarifying all of this. I've got something which I think kind of works, so will factor it into something that makes sense in the (much more complex) project which requires it. I'm happy for you to close this bug now. Cheers Toby -- The University of Edinburgh is a charitable body, registered in Scotland, with registration number SC005336.