bump version to 0.56 and update changes for release
[gitmo/Moose.git] / lib / Moose.pm
index e042a71..fb40886 100644 (file)
@@ -4,7 +4,10 @@ package Moose;
 use strict;
 use warnings;
 
+use 5.008;
+
 our $VERSION   = '0.56';
+$VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
 
 use Scalar::Util 'blessed';
@@ -12,7 +15,7 @@ use Carp         'confess', 'croak', 'cluck';
 
 use Moose::Exporter;
 
-use Class::MOP 0.64;
+use Class::MOP 0.65;
 
 use Moose::Meta::Class;
 use Moose::Meta::TypeConstraint;
@@ -29,7 +32,6 @@ use Moose::Meta::Role::Application::RoleSummation;
 use Moose::Meta::Role::Application::ToClass;
 use Moose::Meta::Role::Application::ToRole;
 use Moose::Meta::Role::Application::ToInstance;
-use Moose::Meta::Role::Application::ToMetaclassInstance;
 
 use Moose::Util::TypeConstraints;
 use Moose::Util ();
@@ -53,7 +55,7 @@ sub extends {
     # this checks the metaclass to make sure
     # it is correct, sometimes it can get out
     # of sync when the classes are being built
-    my $meta = Class::MOP::Class->initialize($class)->_fix_metaclass_incompatability(@supers);
+    my $meta = Moose::Meta::Class->initialize($class)->_fix_metaclass_incompatability(@supers);
     $meta->superclasses(@supers);
 }
 
@@ -162,27 +164,63 @@ sub init_meta {
         unless find_type_constraint($class);
 
     my $meta;
+
+    if ( $meta = Class::MOP::get_metaclass_by_name($class) ) {
+        unless ( $meta->isa("Moose::Meta::Class") ) {
+            confess "$class already has a metaclass, but it does not inherit $metaclass ($meta)";
+        }
+    } else {
+        # no metaclass, no 'meta' method
+
+        # now we check whether our ancestors have metaclass, and if so borrow that
+        my ( undef, @isa ) = @{ $class->mro::get_linear_isa };
+
+        foreach my $ancestor ( @isa ) {
+            my $ancestor_meta = Class::MOP::get_metaclass_by_name($ancestor) || next;
+
+            my $ancestor_meta_class = ($ancestor_meta->is_immutable
+                ? $ancestor_meta->get_mutable_metaclass_name
+                : ref($ancestor_meta));
+
+            # if we have an ancestor metaclass that inherits $metaclass, we use
+            # that. This is like _fix_metaclass_incompatability, but we can do it now.
+
+            # the case of having an ancestry is not very common, but arises in
+            # e.g. Reaction
+            unless ( $metaclass->isa( $ancestor_meta_class ) ) {
+                if ( $ancestor_meta_class->isa($metaclass) ) {
+                    $metaclass = $ancestor_meta_class;
+                }
+            }
+        }
+
+        $meta = $metaclass->initialize($class);
+    }
+
     if ( $class->can('meta') ) {
+        # check 'meta' method
+
+        # it may be inherited
+
         # NOTE:
         # this is the case where the metaclass pragma
         # was used before the 'use Moose' statement to
         # override a specific class
-        $meta = Class::MOP::Class->initialize($class);
-        ( blessed($meta) && $meta->isa('Moose::Meta::Class') )
-          || confess "You already have a &meta function, but it does not return a Moose::Meta::Class";
+        my $method_meta = $class->meta;
+
+        ( blessed($method_meta) && $method_meta->isa('Moose::Meta::Class') )
+            || confess "$class already has a &meta function, but it does not return a Moose::Meta::Class ($meta)";
+
+        $meta = $method_meta;
     }
-    else {
-        # NOTE:
-        # this is broken currently, we actually need
-        # to allow the possiblity of an inherited
-        # meta, which will not be visible until the
-        # user 'extends' first. This needs to have
-        # more intelligence to it
-        $meta = $metaclass->initialize($class);
+
+    unless ( $meta->has_method("meta") ) { # don't overwrite
+        # also check for inherited non moose 'meta' method?
+        # FIXME also skip this if the user requested by passing an option
         $meta->add_method(
             'meta' => sub {
                 # re-initialize so it inherits properly
-                $metaclass->initialize( blessed( $_[0] ) || $_[0] );
+                $metaclass->initialize( ref($_[0]) || $_[0] );
             }
         );
     }
@@ -191,7 +229,6 @@ sub init_meta {
     $meta->superclasses($base_class)
       unless $meta->superclasses();
 
-
     return $meta;
 }
 
@@ -241,7 +278,6 @@ $_->meta->make_immutable(
     Moose::Meta::Role::Application::ToClass
     Moose::Meta::Role::Application::ToRole
     Moose::Meta::Role::Application::ToInstance
-    Moose::Meta::Role::Application::ToMetaclassInstance
 ));
 
 1;