bump version to 0.87
[gitmo/Class-MOP.git] / lib / Class / MOP.pm
index 8b0bd26..dafdc17 100644 (file)
@@ -9,33 +9,30 @@ use 5.008;
 use MRO::Compat;
 
 use Carp          'confess';
-use Devel::GlobalDestruction qw( in_global_destruction );
-use Scalar::Util  'weaken', 'reftype';
-use Sub::Name qw( subname );
+use Scalar::Util  'weaken', 'reftype', 'blessed';
 
 use Class::MOP::Class;
 use Class::MOP::Attribute;
 use Class::MOP::Method;
 
-use Class::MOP::Immutable;
-
 BEGIN {
-    *IS_RUNNING_ON_5_10 = ($] < 5.009_005) 
+    *IS_RUNNING_ON_5_10 = ($] < 5.009_005)
         ? sub () { 0 }
-        : sub () { 1 };    
-
-    *HAVE_ISAREV = defined(&mro::get_isarev)
-        ? sub () { 1 }
         : sub () { 1 };
 
+    sub HAVE_ISAREV () {
+        Carp::cluck("Class::MOP::HAVE_ISAREV is deprecated and will be removed in a future release. It has always returned 1 anyway.");
+        return 1;
+    }
+
     # this is either part of core or set up appropriately by MRO::Compat
     *check_package_cache_flag = \&mro::get_pkg_gen;
 }
 
-our $VERSION   = '0.78_01';
+our $VERSION   = '0.87';
 our $XS_VERSION = $VERSION;
 $VERSION = eval $VERSION;
-our $AUTHORITY = 'cpan:STEVAN';    
+our $AUTHORITY = 'cpan:STEVAN';
 
 require XSLoader;
 XSLoader::load( __PACKAGE__, $XS_VERSION );
@@ -59,6 +56,13 @@ XSLoader::load( __PACKAGE__, $XS_VERSION );
     sub does_metaclass_exist        { exists $METAS{$_[0]} && defined $METAS{$_[0]} }
     sub remove_metaclass_by_name    { $METAS{$_[0]} = undef }
 
+    # This handles instances as well as class names
+    sub class_of {
+        return unless defined $_[0];
+        my $class = blessed($_[0]) || $_[0];
+        return $METAS{$class};
+    }
+
     # NOTE:
     # We only cache metaclasses, meaning instances of
     # Class::MOP::Class. We do not cache instance of
@@ -66,6 +70,15 @@ XSLoader::load( __PACKAGE__, $XS_VERSION );
     # because I don't yet see a good reason to do so.
 }
 
+sub _class_to_pmfile {
+    my $class = shift;
+
+    my $file = $class . '.pm';
+    $file =~ s{::}{/}g;
+
+    return $file;
+}
+
 sub load_first_existing_class {
     my @classes = @_
         or return;
@@ -80,10 +93,12 @@ sub load_first_existing_class {
     my $found;
     my %exceptions;
     for my $class (@classes) {
+        my $pmfile = _class_to_pmfile($class);
         my $e = _try_load_one_class($class);
 
         if ($e) {
             $exceptions{$class} = $e;
+            last if $e !~ /^Can't locate \Q$pmfile\E in \@INC/;
         }
         else {
             $found = $class;
@@ -100,6 +115,9 @@ sub load_first_existing_class {
                 "Could not load class (%s) because : %s", $_,
                 $exceptions{$_}
                 )
+            }
+        grep {
+            exists $exceptions{$_}
             } @classes
     );
 }
@@ -109,11 +127,11 @@ sub _try_load_one_class {
 
     return if is_class_loaded($class);
 
-    my $file = $class . '.pm';
-    $file =~ s{::}{/}g;
+    my $file = _class_to_pmfile($class);
 
     return do {
         local $@;
+        local $SIG{__DIE__};
         eval { require($file) };
         $@;
     };
@@ -136,6 +154,18 @@ sub _is_valid_class_name {
     return 0;
 }
 
+sub subname {
+    require Sub::Name;
+    Carp::carp("Class::MOP::subname is deprecated. Please use Sub::Name directly.");
+    goto \&Sub::Name::subname;
+}
+
+sub in_global_destruction {
+    require Devel::GlobalDestruction;
+    Carp::carp("Class::MOP::in_global_destruction is deprecated. Please use Devel::GlobalDestruction directly.");
+    goto \&Devel::GlobalDestruction::in_global_destruction;
+}
+
 ## ----------------------------------------------------------------------------
 ## Setting up our environment ...
 ## ----------------------------------------------------------------------------
@@ -158,7 +188,7 @@ sub _is_valid_class_name {
 
 # We need to add in the meta-attributes here so that
 # any subclass of Class::MOP::* will be able to
-# inherit them using &construct_instance
+# inherit them using _construct_instance
 
 ## --------------------------------------------------------
 ## Class::MOP::Package
@@ -329,11 +359,47 @@ Class::MOP::Class->meta->add_attribute(
     ))
 );
 
+Class::MOP::Class->meta->add_attribute(
+    Class::MOP::Attribute->new('immutable_trait' => (
+        reader   => {
+            'immutable_trait' => \&Class::MOP::Class::immutable_trait
+        },
+        default => "Class::MOP::Class::Immutable::Trait",
+    ))
+);
+
+Class::MOP::Class->meta->add_attribute(
+    Class::MOP::Attribute->new('constructor_name' => (
+        reader   => {
+            'constructor_name' => \&Class::MOP::Class::constructor_name,
+        },
+        default => "new",
+    ))
+);
+
+Class::MOP::Class->meta->add_attribute(
+    Class::MOP::Attribute->new('constructor_class' => (
+        reader   => {
+            'constructor_class' => \&Class::MOP::Class::constructor_class,
+        },
+        default => "Class::MOP::Method::Constructor",
+    ))
+);
+
+
+Class::MOP::Class->meta->add_attribute(
+    Class::MOP::Attribute->new('destructor_class' => (
+        reader   => {
+            'destructor_class' => \&Class::MOP::Class::destructor_class,
+        },
+    ))
+);
+
 # NOTE:
 # we don't actually need to tie the knot with
 # Class::MOP::Class here, it is actually handled
 # within Class::MOP::Class itself in the
-# construct_class_instance method.
+# _construct_class_instance method.
 
 ## --------------------------------------------------------
 ## Class::MOP::Attribute
@@ -442,6 +508,14 @@ Class::MOP::Attribute->meta->add_attribute(
     ))
 );
 
+Class::MOP::Attribute->meta->add_attribute(
+    Class::MOP::Attribute->new('insertion_order' => (
+        reader      => { 'insertion_order' => \&Class::MOP::Attribute::insertion_order },
+        writer      => { '_set_insertion_order' => \&Class::MOP::Attribute::_set_insertion_order },
+        predicate   => { 'has_insertion_order' => \&Class::MOP::Attribute::has_insertion_order },
+    ))
+);
+
 Class::MOP::Attribute->meta->add_method('clone' => sub {
     my $self  = shift;
     $self->meta->clone_object($self, @_);
@@ -515,6 +589,16 @@ Class::MOP::Method::Generated->meta->add_attribute(
     ))
 );
 
+
+## --------------------------------------------------------
+## Class::MOP::Method::Inlined
+
+Class::MOP::Method::Inlined->meta->add_attribute(
+    Class::MOP::Attribute->new('_expected_method_class' => (
+        reader   => { '_expected_method_class' => \&Class::MOP::Method::Inlined::_expected_method_class },
+    ))
+);
+
 ## --------------------------------------------------------
 ## Class::MOP::Method::Accessor
 
@@ -607,6 +691,10 @@ undef Class::MOP::Instance->meta->{_package_cache_flag};
 # NOTE: we don't need to inline the the accessors this only lengthens
 # the compile time of the MOP, and gives us no actual benefits.
 
+# this is just nitpicking to ensure Class::MOP::Class->meta == ->meta->meta
+Class::MOP::Class->meta->_immutable_metaclass;
+$Class::MOP::Class::immutable_metaclass_cache{"Class::MOP::Class"}{"Class::MOP::Class::Immutable::Trait"} = Class::MOP::Class::Immutable::Class::MOP::Class->meta;
+
 $_->meta->make_immutable(
     inline_constructor  => 1,
     replace_constructor => 1,
@@ -616,6 +704,8 @@ $_->meta->make_immutable(
     Class::MOP::Package
     Class::MOP::Module
     Class::MOP::Class
+    Class::MOP::Class::Immutable::Trait
+    Class::MOP::Class::Immutable::Class::MOP::Class
 
     Class::MOP::Attribute
     Class::MOP::Method
@@ -624,6 +714,7 @@ $_->meta->make_immutable(
     Class::MOP::Object
 
     Class::MOP::Method::Generated
+    Class::MOP::Method::Inlined
 
     Class::MOP::Method::Accessor
     Class::MOP::Method::Constructor
@@ -831,11 +922,6 @@ We set this constant depending on what version perl we are on, this
 allows us to take advantage of new 5.10 features and stay backwards
 compatible.
 
-=item I<Class::MOP::HAVE_ISAREV>
-
-Whether or not the L<mro> pragma provides C<get_isarev>, a much faster
-way to get all the subclasses of a certain class.
-
 =back
 
 =head2 Utility functions
@@ -846,9 +932,11 @@ Note that these are all called as B<functions, not methods>.
 
 =item B<Class::MOP::load_class($class_name)>
 
-This will load the specified C<$class_name>. This function can be used
+This will load the specified C<$class_name>, if it is not already
+loaded (as reported by C<is_class_loaded>). This function can be used
 in place of tricks like C<eval "use $module"> or using C<require>
-unconditionally.
+unconditionally. This will return the metaclass of C<$class_name> if
+one exists, otherwise it will return C<$class_name>.
 
 =item B<Class::MOP::is_class_loaded($class_name)>
 
@@ -858,7 +946,9 @@ loaded.
 This does a basic check of the symbol table to try and determine as
 best it can if the C<$class_name> is loaded, it is probably correct
 about 99% of the time, but it can be fooled into reporting false
-positives.
+positives. In particular, loading any of the core L<IO> modules will
+cause most of the rest of the core L<IO> modules to falsely report
+having been loaded, due to the way the base L<IO> module works.
 
 =item B<Class::MOP::get_code_info($code)>
 
@@ -867,6 +957,12 @@ is from and the name of the C<$code> itself. This is used by several
 elements of the MOP to determine where a given C<$code> reference is
 from.
 
+=item B<Class::MOP::class_of($instance_or_class_name)>
+
+This will return the metaclass of the given instance or class name.  If the
+class lacks a metaclass, no metaclass will be initialized, and C<undef> will be
+returned.
+
 =item B<Class::MOP::check_package_cache_flag($pkg)>
 
 B<NOTE: DO NOT USE THIS FUNCTION, IT IS FOR INTERNAL USE ONLY!>
@@ -1023,8 +1119,14 @@ creates are very different from this modules.
 =head1 BUGS
 
 All complex software has bugs lurking in it, and this module is no
-exception. If you find a bug please either email me, or add the bug
-to cpan-RT.
+exception.
+
+Please report any bugs to C<bug-class-mop@rt.cpan.org>, or through the
+web interface at L<http://rt.cpan.org>.
+
+You can also discuss feature requests or possible bugs on the Moose
+mailing list (moose@perl.org) or on IRC at
+L<irc://irc.perl.org/#moose>.
 
 =head1 ACKNOWLEDGEMENTS
 
@@ -1048,6 +1150,8 @@ Florian (rafl) Ragwitz
 
 Guillermo (groditi) Roditi
 
+Dave (autarch) Rolsky
+
 Matt (mst) Trout
 
 Rob (robkinyon) Kinyon
@@ -1056,6 +1160,8 @@ Yuval (nothingmuch) Kogman
 
 Scott (konobi) McWhirter
 
+Dylan Hardison
+
 =head1 COPYRIGHT AND LICENSE
 
 Copyright 2006-2009 by Infinity Interactive, Inc.