first pass at allowing Moose and Moose::Role to omit the meta method
Jesse Luehrs [Sat, 25 Sep 2010 21:19:04 +0000 (16:19 -0500)]
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).

lib/Moose.pm
lib/Moose/Exporter.pm
lib/Moose/Role.pm

index 537a923..56a70c7 100644 (file)
@@ -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;
     }
 
index 4e87db8..1064050 100644 (file)
@@ -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 ) = @_;
 
index ba49370..700ca66 100644 (file)
@@ -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;
     }