From: Dagfinn Ilmari Mannsåker Date: Mon, 29 Oct 2012 00:03:37 +0000 (+0000) Subject: fix method modifier breakage on 5.10.0 X-Git-Tag: v1.002003~2 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=c49b0f7246784889a22207f69e841c88584bd812;p=gitmo%2FRole-Tiny.git fix method modifier breakage on 5.10.0 Setting @ISA via the typeglob breaks inheritance on 5.10.0 if the stash has previously been accessed an then a method called on the class (in that order!). Add test nicked from Moo that tickles the bug. --- diff --git a/Changes b/Changes index e87de5f..a82a746 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,5 @@ + - fix method modifier breakage on 5.10.0 + 1.002002 - 2012-10-28 - skip t/around-does.t when Class::Method::Modifiers is not installed (RT#80310) diff --git a/lib/Role/Tiny.pm b/lib/Role/Tiny.pm index 3062e65..253d80a 100644 --- a/lib/Role/Tiny.pm +++ b/lib/Role/Tiny.pm @@ -214,7 +214,11 @@ sub _composable_package_for { return $composed_name if $COMPOSED{role}{$composed_name}; $me->_install_methods($composed_name, $role); my $base_name = $composed_name.'::_BASE'; - *{_getglob("${composed_name}::ISA")} = [ $base_name ]; + # Not using _getglob, since setting @ISA via the typeglob breaks + # inheritance on 5.10.0 if the stash has previously been accessed an + # then a method called on the class (in that order!), which + # ->_install_methods (with the help of ->_install_does) ends up doing. + { no strict 'refs'; @{"${composed_name}::ISA"} = ( $base_name ); } my $modifiers = $INFO{$role}{modifiers}||[]; my @mod_base; foreach my $modified ( diff --git a/t/compose-modifiers.t b/t/compose-modifiers.t new file mode 100644 index 0000000..1e67ffc --- /dev/null +++ b/t/compose-modifiers.t @@ -0,0 +1,36 @@ +use strictures 1; +use Test::More; + +BEGIN { + plan skip_all => "Class::Method::Modifiers not installed" + unless eval "use Class::Method::Modifiers; 1"; +} + +{ + package One; use Role::Tiny; + around foo => sub { my $orig = shift; (__PACKAGE__, $orig->(@_)) }; + package Two; use Role::Tiny; + around foo => sub { my $orig = shift; (__PACKAGE__, $orig->(@_)) }; + package Three; use Role::Tiny; + around foo => sub { my $orig = shift; (__PACKAGE__, $orig->(@_)) }; + package Four; use Role::Tiny; + around foo => sub { my $orig = shift; (__PACKAGE__, $orig->(@_)) }; + package Base; sub foo { __PACKAGE__ } +} + +foreach my $combo ( + [ qw(One Two Three Four) ], + [ qw(Two Four Three) ], + [ qw(One Two) ] +) { + my $combined = Role::Tiny->create_class_with_roles('Base', @$combo); + is_deeply( + [ $combined->foo ], [ reverse(@$combo), 'Base' ], + "${combined} ok" + ); + my $object = bless({}, 'Base'); + Role::Tiny->apply_roles_to_object($object, @$combo); + is(ref($object), $combined, 'Object reblessed into correct class'); +} + +done_testing;