X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FMeta%2FRole.pm;h=3a459f47234d65dc7c4620f3fd63f861f858b47e;hb=704926bb5392cb729e71cd7dcab0b59173e53b17;hp=32f7a0b236c49de650cbc30345ec15ff258abc15;hpb=60f0816092ffe11986388dd2bba56a356b697843;p=gitmo%2FMoose.git diff --git a/lib/Moose/Meta/Role.pm b/lib/Moose/Meta/Role.pm index 32f7a0b..3a459f4 100644 --- a/lib/Moose/Meta/Role.pm +++ b/lib/Moose/Meta/Role.pm @@ -9,7 +9,7 @@ use Scalar::Util 'blessed'; use Carp 'confess'; use Devel::GlobalDestruction 'in_global_destruction'; -our $VERSION = '1.09'; +our $VERSION = '1.15'; $VERSION = eval $VERSION; our $AUTHORITY = 'cpan:STEVAN'; @@ -18,12 +18,16 @@ use Moose::Meta::Role::Attribute; use Moose::Meta::Role::Method; use Moose::Meta::Role::Method::Required; use Moose::Meta::Role::Method::Conflicting; +use Moose::Meta::Method::Meta; use Moose::Util qw( ensure_all_roles ); +use Class::MOP::MiniTrait; use base 'Class::MOP::Module', 'Class::MOP::Mixin::HasAttributes', 'Class::MOP::Mixin::HasMethods'; +Class::MOP::MiniTrait::apply(__PACKAGE__, 'Moose::Meta::Object::Trait'); + ## ------------------------------------------------------------------ ## NOTE: ## I normally don't do this, but I am doing @@ -157,12 +161,22 @@ $META->add_attribute( sub initialize { my $class = shift; my $pkg = shift; - return Class::MOP::get_metaclass_by_name($pkg) - || $class->SUPER::initialize( + + if (defined(my $meta = Class::MOP::get_metaclass_by_name($pkg))) { + return $meta; + } + + my %options = @_; + + my $meta = $class->SUPER::initialize( $pkg, 'attribute_metaclass' => 'Moose::Meta::Role::Attribute', - @_ - ); + %options, + ); + + Class::MOP::weaken_metaclass($pkg) if $options{weaken}; + + return $meta; } sub reinitialize { @@ -185,11 +199,31 @@ sub reinitialize { ); } - return $self->SUPER::reinitialize( + my %options = @_; + $options{weaken} = Class::MOP::metaclass_is_weak($meta->name) + if !exists $options{weaken} + && blessed($meta) + && $meta->isa('Moose::Meta::Role'); + + # don't need to remove generated metaobjects here yet, since we don't + # yet generate anything in roles. this may change in the future though... + # keep an eye on that + my $new_meta = $self->SUPER::reinitialize( $pkg, %existing_classes, - @_, + %options, ); + $new_meta->_restore_metaobjects_from($meta) + if $meta && $meta->isa('Moose::Meta::Role'); + return $new_meta; +} + +sub _restore_metaobjects_from { + my $self = shift; + my ($old_meta) = @_; + + $self->_restore_metamethods_from($old_meta); + $self->_restore_metaattributes_from($old_meta); } sub add_attribute { @@ -348,6 +382,7 @@ sub update_package_cache_flag { } +sub _meta_method_class { 'Moose::Meta::Method::Meta' } ## ------------------------------------------------------------------ ## subroles @@ -460,11 +495,15 @@ sub create { || confess "You must pass a HASH ref of methods" if exists $options{methods}; + $options{meta_name} = 'meta' + unless exists $options{meta_name}; + my (%initialize_options) = %options; delete @initialize_options{qw( package attributes methods + meta_name version authority )}; @@ -473,10 +512,8 @@ sub create { $meta->_instantiate_module( $options{version}, $options{authority} ); - # FIXME totally lame - $meta->add_method('meta' => sub { - $role->initialize(ref($_[0]) || $_[0]); - }); + $meta->_add_meta_method($options{meta_name}) + if defined $options{meta_name}; if (exists $options{attributes}) { foreach my $attribute_name (keys %{$options{attributes}}) { @@ -492,9 +529,6 @@ sub create { } } - Class::MOP::weaken_metaclass($meta->name) - if $meta->is_anon_role; - return $meta; } @@ -536,6 +570,7 @@ sub consumers { sub create_anon_role { my ($role, %options) = @_; + $options{weaken} = 1 unless exists $options{weaken}; my $package_name = $ANON_ROLE_PREFIX . ++$ANON_ROLE_SERIAL; return $role->create($package_name, %options); }