Skip Menu |

This queue is for tickets about the Moose CPAN distribution.

Report information
The Basics
Id: 84563
Status: resolved
Priority: 0/
Queue: Moose

People
Owner: Nobody in particular
Requestors: KENTNL [...] cpan.org
Cc:
AdminCc:

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



Subject: Generated accessors metamethod objects should probably have "original_package" pointing to the role that defined them
In the event that you have
package SomeRole;
use Moose::Role;
has 'foo' => ( ... );

package Consumer;
with 'SomeRole';

 

Trying to determine which package provided the generated accessor 'foo' proves unintuitive:

Consumer->meta->get_method('foo')->original_package_name()

reports that 'foo' comes from the 'Consumer' class, not, as you would expect, the role that defined it, 'SomeRole'

Attached is a simple test that tests for this problem, with the 4 common accessor types.

Subject: moose_inheritance.pl
#!/usr/bin/env perl use strict; use warnings; use Test::More; BEGIN { package Some::Role; use Moose::Role; has 'rubbish' => ( reader => '_rubbish_reader', writer => '_rubbish_writer', predicate => '_rubbish_predicate', clearer => '_rubbish_clearer', builder => '_build_rubbish', required => 1 ); sub _build_rubbish { 1 } no Moose::Role; } BEGIN { package Child; use Moose; with 'Some::Role'; __PACKAGE__->meta->make_immutable; no Moose; $INC{'Child.pm'} = 1; } my $meta = Child->meta(); use Scalar::Util qw( blessed ); for my $method_name ( sort $meta->get_method_list ) { my $method = $meta->get_method($method_name); next if $method_name =~ /^(DESTROY|meta|new)$/; isnt( $method->original_package_name, 'Child', "$method_name should not come from Child" ); } done_testing;
I took a look at this and fixing it is somewhat involved. The way the original_package_name is stored in the Method object right now involves just storing a metamethod object and looking at its package. We'd have to change this so that we stored the package name directly as well. I added this test as a TODO test to the test suite.
https://github.com/moose/Moose/pull/134 addresses this. Since you can go from accessor to attribute in class to attribute in role, you can now determine that the role caused the accessor to be generated. I also realized that since the accessor does not exist in the role, it would be wrong for the $accessor->original_package_name method to return the role. There really is no such method in the role at all. I've removed the TODO test I added way back when, since I think this PR solves this problem much more correctly.
On 2016-09-17 13:34:04, DROLSKY wrote: Show quoted text
> https://github.com/moose/Moose/pull/134 addresses this. Since you can > go from accessor to attribute in class to attribute in role, you can > now determine that the role caused the accessor to be generated. > > I also realized that since the accessor does not exist in the role, it > would be wrong for the $accessor->original_package_name method to > return the role. There really is no such method in the role at all. > I've removed the TODO test I added way back when, since I think this > PR solves this problem much more correctly.
This has been merged and will be in 2.1806. thanks!