From: Jesse Luehrs Date: Sat, 25 Sep 2010 21:19:04 +0000 (-0500) Subject: first pass at allowing Moose and Moose::Role to omit the meta method X-Git-Tag: 1.15~32 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=d65bfd76df13cfc72b5a74d6108cf4571b6bf23d;p=gitmo%2FMoose.git first pass at allowing Moose and Moose::Role to omit the meta method not currently working because of issues with metaclass reinitialization... if someone uses a metarole type thing after moose installs the meta method, it gets turned back into a regular Moose::Meta::Method object, and so a bunch of checks don't work correctly (this is the cause of the warnings in the test suite). --- diff --git a/lib/Moose.pm b/lib/Moose.pm index 537a923..56a70c7 100644 --- a/lib/Moose.pm +++ b/lib/Moose.pm @@ -198,9 +198,16 @@ sub init_meta { $meta = $metaclass->initialize($class); } - unless ( $meta->has_method("meta") ) { # don't overwrite + unless ($args{no_meta}) { # also check for inherited non moose 'meta' method? - # FIXME also skip this if the user requested by passing an option + my $existing = $meta->get_method('meta'); + if ($existing && !$existing->isa('Class::MOP::Method::Meta')) { + warn "Moose is overwriting an existing method named 'meta' " + . "with its own version, in class $class. If this is actually " + . "what you want, you should remove the existing method, " + . "otherwise, you should pass the '-no_meta => 1' option to " + . "'use Moose'."; + } $meta->_add_meta_method; } diff --git a/lib/Moose/Exporter.pm b/lib/Moose/Exporter.pm index 4e87db8..1064050 100644 --- a/lib/Moose/Exporter.pm +++ b/lib/Moose/Exporter.pm @@ -357,6 +357,9 @@ sub _make_import_sub { = Moose::Util::resolve_metaclass_alias( 'Class' => $metaclass ) if defined $metaclass && length $metaclass; + my $no_meta; + ( $no_meta, @_ ) = _strip_no_meta(@_); + # Normally we could look at $_[0], but in some weird cases # (involving goto &Moose::import), $_[0] ends as something # else (like Squirrel). @@ -380,7 +383,11 @@ sub _make_import_sub { # Moose::Exporter, which in turn sets $CALLER, so we need # to protect against that. local $CALLER = $CALLER; - $c->init_meta( for_class => $CALLER, metaclass => $metaclass ); + $c->init_meta( + for_class => $CALLER, + metaclass => $metaclass, + no_meta => $no_meta, + ); $did_init_meta = 1; } @@ -444,6 +451,18 @@ sub _strip_metaclass { return ( $metaclass, @_ ); } +sub _strip_no_meta { + my $idx = first_index { $_ eq '-no_meta' } @_; + + return ( undef, @_ ) unless $idx >= 0 && $#_ >= $idx + 1; + + my $no_meta = $_[ $idx + 1 ]; + + splice @_, $idx, 2; + + return ( $no_meta, @_ ); +} + sub _apply_meta_traits { my ( $class, $traits ) = @_; diff --git a/lib/Moose/Role.pm b/lib/Moose/Role.pm index ba49370..700ca66 100644 --- a/lib/Moose/Role.pm +++ b/lib/Moose/Role.pm @@ -133,9 +133,16 @@ sub init_meta { $meta = $metaclass->initialize($role); } - unless ( $meta->has_method("meta") ) { # don't overwrite + unless ($args{no_meta}) { # also check for inherited non moose 'meta' method? - # FIXME also skip this if the user requested by passing an option + my $existing = $meta->get_method('meta'); + if ($existing && !$existing->isa('Class::MOP::Method::Meta')) { + warn "Moose::Role is overwriting an existing method named 'meta' " + . "with its own version, in role $role. If this is actually " + . "what you want, you should remove the existing method, " + . "otherwise, you should pass the '-no_meta => 1' option to " + . "'use Moose::Role'."; + } $meta->_add_meta_method; }