0.27
* fixing some misc. bits in the docs that
got mentioned on CPAN Forum
+
+ * Moose::Meta::Role
+ - fixed how required methods are handled
+ when they encounter overriden or modified
+ methods from a class (thanks to confound).
+ - added tests for this
0.26 Thurs. Sept. 27, 2007
== New Features ==
Christian (chansen) Hansen
+Hans Dieter (confound) Pearcey
+
Eric (ewilhelm) Wilhelm
Guillermo (groditi) Roditi
use Scalar::Util 'blessed';
use B 'svref_2object';
-our $VERSION = '0.09';
+our $VERSION = '0.10';
our $AUTHORITY = 'cpan:STEVAN';
use Moose::Meta::Class;
# not a method modifier, because those do
# not satisfy the requirements ...
my $method = $other->find_method_by_name($required_method_name);
- # check if it is an override or a generated accessor ..
- ($method->isa('Class::MOP::Method::Accessor'))
- && confess "'" . $self->name . "' requires the method '$required_method_name' " .
- "to be implemented by '" . $other->name . "', the method is only an attribute";
- # before/after/around methods are a little trickier
- # since we wrap the original local method (if applicable)
- # so we need to check if the original wrapped method is
- # from the same package, and not a wrap of the super method
- if ($method->isa('Class::MOP::Method::Wrapped') ||
- $method->isa('Moose::Meta::Method::Overriden')) {
- ($other->name->isa($method->get_original_method->package_name))
- || confess "'" . $self->name . "' requires the method '$required_method_name' " .
- "to be implemented by '" . $other->name . "', the method is only a method modifier";
- }
+
+ # check if it is a generated accessor ...
+ (!$method->isa('Class::MOP::Method::Accessor'))
+ || confess "'" . $self->name . "' requires the method '$required_method_name' " .
+ "to be implemented by '" . $other->name . "', the method is only an attribute accessor";
+
+ # NOTE:
+ # All other tests here have been removed, they were tests
+ # for overriden methods and before/after/around modifiers.
+ # But we realized that for classes any overriden or modified
+ # methods would be backed by a real method of that name
+ # (and therefore meet the requirement). And for roles, the
+ # overriden and modified methods are "in statis" and so would
+ # not show up in this test anyway (and as a side-effect they
+ # would not fufill the requirement, which is exactly what we
+ # want them to do anyway).
+ # - SL
}
}
}
use strict;
use warnings;
-use Test::More tests => 19;
+use Test::More tests => 17;
use Test::Exception;
=pod
override 'foo' => sub { 'Class::ProvideFoo::foo' };
- ::dies_ok {
+ ::lives_ok {
with 'Role::RequireFoo';
- } '... the required "foo" method exists, but it is an override (and we will die)';
+ } '... the required "foo" method exists, although it is overriden locally';
}
before 'foo' => sub { 'Class::ProvideFoo::foo:before' };
- ::dies_ok {
+ ::lives_ok {
with 'Role::RequireFoo';
- } '... the required "foo" method exists, but it is a before (and we will die)';
+ } '... the required "foo" method exists, although it is a before modifier locally';
package Class::ProvideFoo::Before3;
use Moose;
extends 'Class::ProvideFoo::Base';
- ::lives_ok {
- with 'Role::RequireFoo';
- } '... the required "foo" method will not exist yet (and we will die)';
-
sub foo { 'Class::ProvideFoo::foo' }
before 'foo' => sub { 'Class::ProvideFoo::foo:before' };
+ ::lives_ok {
+ with 'Role::RequireFoo';
+ } '... the required "foo" method exists locally, and it is modified locally';
+
package Class::ProvideFoo::Before4;
use Moose;
::lives_ok {
with 'Role::RequireFoo';
} '... the required "foo" method exists in the symbol table (and we will live)';
-
- package Class::ProvideFoo::Before5;
- use Moose;
-
- extends 'Class::ProvideFoo::Base';
-
- before 'foo' => sub { 'Class::ProvideFoo::foo:before' };
-
- ::isa_ok(__PACKAGE__->meta->get_method('foo'), 'Class::MOP::Method::Wrapped');
- ::isnt(__PACKAGE__->meta->get_method('foo')->get_original_method->package_name, __PACKAGE__,
- '... but the original method is not from our package');
-
- ::dies_ok {
- with 'Role::RequireFoo';
- } '... the required "foo" method exists, but it is a before wrapping the super (and we will die)';
+
}
=pod
with 'Bar::Role';
} 'required method exists in superclass as non-modifier, so we live';
}
+
+{
+ package Bar2::Class::Base;
+ use Moose;
+
+ sub bar { "hello!" }
+}
+{
+ package Bar2::Role;
+ use Moose::Role;
+ requires 'bar';
+}
+{
+ package Bar2::Class::Child;
+ use Moose;
+ extends 'Bar2::Class::Base';
+ override bar => sub { "o noes" };
+ # technically we could run lives_ok here, too, but putting it into a
+ # grandchild class makes it more obvious why this matters.
+}
+{
+ package Bar2::Class::Grandchild;
+ use Moose;
+ extends 'Bar2::Class::Child';
+ ::lives_ok {
+ with 'Bar2::Role';
+ } 'required method exists in superclass as non-modifier, so we live';
+}