Finance-FITF
view release on metacpan or search on metacpan
inc/Class/MOP/Class.pm view on Meta::CPAN
#line 1
package Class::MOP::Class;
BEGIN {
$Class::MOP::Class::AUTHORITY = 'cpan:STEVAN';
}
BEGIN {
$Class::MOP::Class::VERSION = '2.0009';
}
use strict;
use warnings;
use Class::MOP::Instance;
use Class::MOP::Method::Wrapped;
use Class::MOP::Method::Accessor;
use Class::MOP::Method::Constructor;
use Class::MOP::MiniTrait;
use Carp 'confess';
use Scalar::Util 'blessed', 'reftype', 'weaken';
use Sub::Name 'subname';
use Try::Tiny;
use List::MoreUtils 'all';
use base 'Class::MOP::Module',
'Class::MOP::Mixin::HasAttributes',
'Class::MOP::Mixin::HasMethods';
# Creation
sub initialize {
my $class = shift;
my $package_name;
if ( @_ % 2 ) {
$package_name = shift;
} else {
my %options = @_;
$package_name = $options{package};
}
($package_name && !ref($package_name))
|| confess "You must pass a package name and it cannot be blessed";
return Class::MOP::get_metaclass_by_name($package_name)
|| $class->_construct_class_instance(package => $package_name, @_);
}
sub reinitialize {
my ( $class, @args ) = @_;
unshift @args, "package" if @args % 2;
my %options = @args;
my $old_metaclass = blessed($options{package})
? $options{package}
: Class::MOP::get_metaclass_by_name($options{package});
$options{weaken} = Class::MOP::metaclass_is_weak($old_metaclass->name)
if !exists $options{weaken}
&& blessed($old_metaclass)
&& $old_metaclass->isa('Class::MOP::Class');
$old_metaclass->_remove_generated_metaobjects
if $old_metaclass && $old_metaclass->isa('Class::MOP::Class');
my $new_metaclass = $class->SUPER::reinitialize(%options);
$new_metaclass->_restore_metaobjects_from($old_metaclass)
if $old_metaclass && $old_metaclass->isa('Class::MOP::Class');
return $new_metaclass;
}
# NOTE: (meta-circularity)
# this is a special form of _construct_instance
# (see below), which is used to construct class
# meta-object instances for any Class::MOP::*
# class. All other classes will use the more
# normal &construct_instance.
sub _construct_class_instance {
my $class = shift;
my $options = @_ == 1 ? $_[0] : {@_};
my $package_name = $options->{package};
(defined $package_name && $package_name)
|| confess "You must pass a package name";
# NOTE:
# return the metaclass if we have it cached,
# and it is still defined (it has not been
# reaped by DESTROY yet, which can happen
# annoyingly enough during global destruction)
if (defined(my $meta = Class::MOP::get_metaclass_by_name($package_name))) {
return $meta;
}
$class
= ref $class
? $class->_real_ref_name
: $class;
# now create the metaclass
my $meta;
if ($class eq 'Class::MOP::Class') {
$meta = $class->_new($options);
}
else {
# NOTE:
# it is safe to use meta here because
# class will always be a subclass of
# Class::MOP::Class, which defines meta
$meta = $class->meta->_construct_instance($options)
}
# and check the metaclass compatibility
$meta->_check_metaclass_compatibility();
Class::MOP::store_metaclass_by_name($package_name, $meta);
# NOTE:
# we need to weaken any anon classes
# so that they can call DESTROY properly
Class::MOP::weaken_metaclass($package_name) if $options->{weaken};
$meta;
}
sub _real_ref_name {
my $self = shift;
# NOTE: we need to deal with the possibility of class immutability here,
# and then get the name of the class appropriately
return $self->is_immutable
? $self->_get_mutable_metaclass_name()
: ref $self;
}
sub _new {
my $class = shift;
return Class::MOP::Class->initialize($class)->new_object(@_)
if $class ne __PACKAGE__;
my $options = @_ == 1 ? $_[0] : {@_};
return bless {
# inherited from Class::MOP::Package
'package' => $options->{package},
# NOTE:
# since the following attributes will
# actually be loaded from the symbol
# table, and actually bypass the instance
# entirely, we can just leave these things
# listed here for reference, because they
# should not actually have a value associated
# with the slot.
'namespace' => \undef,
'methods' => {},
# inherited from Class::MOP::Module
'version' => \undef,
'authority' => \undef,
# defined in Class::MOP::Class
'superclasses' => \undef,
'attributes' => {},
'attribute_metaclass' =>
( $options->{'attribute_metaclass'} || 'Class::MOP::Attribute' ),
'method_metaclass' =>
( $options->{'method_metaclass'} || 'Class::MOP::Method' ),
'wrapped_method_metaclass' => (
$options->{'wrapped_method_metaclass'}
|| 'Class::MOP::Method::Wrapped'
),
'instance_metaclass' =>
( $options->{'instance_metaclass'} || 'Class::MOP::Instance' ),
'immutable_trait' => (
$options->{'immutable_trait'}
|| 'Class::MOP::Class::Immutable::Trait'
),
'constructor_name' => ( $options->{constructor_name} || 'new' ),
( run in 1.894 second using v1.01-cache-2.11-cpan-d8267643d1d )