bump the Class::MOP dep to 0.64_07
[gitmo/Moose.git] / lib / Moose.pm
index 2b5a079..57aa556 100644 (file)
@@ -4,7 +4,10 @@ package Moose;
 use strict;
 use warnings;
 
-our $VERSION   = '0.56';
+use 5.008;
+
+our $VERSION   = '0.55_02';
+$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.6407;
 
 use Moose::Meta::Class;
 use Moose::Meta::TypeConstraint;
@@ -20,9 +23,17 @@ use Moose::Meta::TypeCoercion;
 use Moose::Meta::Attribute;
 use Moose::Meta::Instance;
 
+use Moose::Object;
+
 use Moose::Meta::Role;
+use Moose::Meta::Role::Composite;
+use Moose::Meta::Role::Application;
+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::Object;
 use Moose::Util::TypeConstraints;
 use Moose::Util ();
 
@@ -45,13 +56,13 @@ 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->meta->_fix_metaclass_incompatability(@supers);
+    my $meta = Moose::Meta::Class->initialize($class)->_fix_metaclass_incompatability(@supers);
     $meta->superclasses(@supers);
 }
 
 sub with {
     my $class = shift;
-    Moose::Util::apply_all_roles($class->meta, @_);
+    Moose::Util::apply_all_roles(Class::MOP::Class->initialize($class), @_);
 }
 
 sub has {
@@ -60,7 +71,7 @@ sub has {
     croak 'Usage: has \'name\' => ( key => value, ... )' if @_ == 1;
     my %options = @_;
     my $attrs = ( ref($name) eq 'ARRAY' ) ? $name : [ ($name) ];
-    $class->meta->add_attribute( $_, %options ) for @$attrs;
+    Class::MOP::Class->initialize($class)->add_attribute( $_, %options ) for @$attrs;
 }
 
 sub before {
@@ -85,7 +96,7 @@ sub super {
 sub override {
     my $class = shift;
     my ( $name, $method ) = @_;
-    $class->meta->add_override_method_modifier( $name => $method );
+    Class::MOP::Class->initialize($class)->add_override_method_modifier( $name => $method );
 }
 
 sub inner {
@@ -105,17 +116,17 @@ sub inner {
 sub augment {
     my $class = shift;
     my ( $name, $method ) = @_;
-    $class->meta->add_augment_method_modifier( $name => $method );
+    Class::MOP::Class->initialize($class)->add_augment_method_modifier( $name => $method );
 }
 
 sub make_immutable {
     my $class = shift;
     cluck "The make_immutable keyword has been deprecated, " . 
           "please go back to __PACKAGE__->meta->make_immutable\n";
-    $class->meta->make_immutable(@_);
+    Class::MOP::Class->initialize($class)->make_immutable(@_);
 }
 
-my $exporter = Moose::Exporter->build_import_methods(
+Moose::Exporter->setup_import_methods(
     with_caller => [
         qw( extends with has before after around override augment make_immutable )
     ],
@@ -154,27 +165,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->meta();
-        ( 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] );
             }
         );
     }
@@ -183,7 +230,6 @@ sub init_meta {
     $meta->superclasses($base_class)
       unless $meta->superclasses();
 
-
     return $meta;
 }
 
@@ -195,29 +241,46 @@ sub _get_caller {
 ## make 'em all immutable
 
 $_->meta->make_immutable(
-    inline_constructor => 0,
+    inline_constructor => 1,
+    constructor_name   => "_new",
     inline_accessors   => 1,  # these are Class::MOP accessors, so they need inlining
   )
-  for (
-    'Moose::Meta::Attribute',
-    'Moose::Meta::Class',
-    'Moose::Meta::Instance',
-
-    'Moose::Meta::TypeConstraint',
-    'Moose::Meta::TypeConstraint::Union',
-    'Moose::Meta::TypeConstraint::Parameterized',
-    'Moose::Meta::TypeCoercion',
-
-    'Moose::Meta::Method',
-    'Moose::Meta::Method::Accessor',
-    'Moose::Meta::Method::Constructor',
-    'Moose::Meta::Method::Destructor',
-    'Moose::Meta::Method::Overriden',
-
-    'Moose::Meta::Role',
-    'Moose::Meta::Role::Method',
-    'Moose::Meta::Role::Method::Required',
-  );
+  for (qw(
+    Moose::Meta::Attribute
+    Moose::Meta::Class
+    Moose::Meta::Instance
+
+    Moose::Meta::TypeConstraint
+    Moose::Meta::TypeConstraint::Union
+    Moose::Meta::TypeConstraint::Parameterized
+    Moose::Meta::TypeConstraint::Parameterizable
+    Moose::Meta::TypeConstraint::Enum
+    Moose::Meta::TypeConstraint::Class
+    Moose::Meta::TypeConstraint::Role
+    Moose::Meta::TypeConstraint::Registry
+    Moose::Meta::TypeCoercion
+    Moose::Meta::TypeCoercion::Union
+
+    Moose::Meta::Method
+    Moose::Meta::Method::Accessor
+    Moose::Meta::Method::Constructor
+    Moose::Meta::Method::Destructor
+    Moose::Meta::Method::Overriden
+    Moose::Meta::Method::Augmented
+
+    Moose::Meta::Role
+    Moose::Meta::Role::Method
+    Moose::Meta::Role::Method::Required
+
+    Moose::Meta::Role::Composite
+
+    Moose::Meta::Role::Application
+    Moose::Meta::Role::Application::RoleSummation
+    Moose::Meta::Role::Application::ToClass
+    Moose::Meta::Role::Application::ToRole
+    Moose::Meta::Role::Application::ToInstance
+    Moose::Meta::Role::Application::ToMetaclassInstance
+));
 
 1;
 
@@ -268,6 +331,14 @@ metaclass system for Perl 5. This means that Moose not only makes
 building normal Perl 5 objects better, but it provides the power of 
 metaclass programming as well. 
 
+=head2 New to Moose?
+
+If you're new to Moose, the best place to start is the
+L<Moose::Cookbook>. The recipes on Moose basics will get you up to
+speed with many of Moose's features quickly. Once you have an idea of
+what Moose can do, you can use the API documentation to get more
+detail on features which interest you.
+
 =head2 Moose Extensions
 
 The C<MooseX::> namespace is the official place to find Moose extensions.
@@ -768,7 +839,7 @@ Here is a simple example:
     use Moose (); # no need to get Moose's exports
     use Moose::Exporter;
 
-    Moose::Exporter->build_import_methods( also => 'Moose' );
+    Moose::Exporter->setup_import_methods( also => 'Moose' );
 
     sub init_meta {
         shift;
@@ -794,7 +865,7 @@ For more detail on this topic, see L<Moose::Cookbook::Extending::Recipe2>.
 
 This method used to be documented as a function which accepted
 positional parameters. This calling style will still work for
-backwards compatibility.
+backwards compatibility, but is deprecated.
 
 =head2 B<import>