X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FMouse.git;a=blobdiff_plain;f=lib%2FMouse%2FMeta%2FClass.pm;h=3113b83514791a0f3139b022f2d69a3ccb14036d;hp=6fcb5768b371ab9edda220c0debafd82ab46217f;hb=ff6870694bb440c13826e0f0fa25e760247fd24e;hpb=6cfa1e5e70616fb102915489c02d8347ffa912fb diff --git a/lib/Mouse/Meta/Class.pm b/lib/Mouse/Meta/Class.pm index 6fcb576..3113b83 100644 --- a/lib/Mouse/Meta/Class.pm +++ b/lib/Mouse/Meta/Class.pm @@ -285,6 +285,7 @@ sub does_role { next unless $meta && $meta->can('roles'); for my $role (@{ $meta->roles }) { + return 1 if $role->does_role($role_name); } } @@ -307,19 +308,18 @@ sub create { || $class->throw_error("You must pass a HASH ref of methods") if exists $options{methods}; - do { + (ref $options{roles} eq 'ARRAY') + || $class->throw_error("You must pass an ARRAY ref of roles") + if exists $options{roles}; + + { ( defined $package_name && $package_name ) || $class->throw_error("You must pass a package name"); - my $code = "package $package_name;"; - $code .= "\$$package_name\:\:VERSION = '" . $options{version} . "';" - if exists $options{version}; - $code .= "\$$package_name\:\:AUTHORITY = '" . $options{authority} . "';" - if exists $options{authority}; - - eval $code; - $class->throw_error("creation of $package_name failed : $@") if $@; - }; + no strict 'refs'; + ${ $package_name . '::VERSION' } = $options{version} if exists $options{version}; + ${ $package_name . '::AUTHORITY' } = $options{authority} if exists $options{authority}; + } my %initialize_options = %options; delete @initialize_options{qw( @@ -327,6 +327,7 @@ sub create { superclasses attributes methods + roles version authority )}; @@ -354,17 +355,67 @@ sub create { $meta->add_method($method_name, $options{methods}->{$method_name}); } } + if (exists $options{roles}){ + Mouse::Util::apply_all_roles($package_name, @{$options{roles}}); + } return $meta; } { my $ANON_CLASS_SERIAL = 0; my $ANON_CLASS_PREFIX = 'Mouse::Meta::Class::__ANON__::SERIAL::'; + + my %IMMORTAL_ANON_CLASSES; sub create_anon_class { my ( $class, %options ) = @_; + + my $cache = $options{cache}; + my $cache_key; + + if($cache){ # anonymous but not mortal + # something like Super::Class|Super::Class::2=Role|Role::1 + $cache_key = join '=' => ( + join('|', @{$options{superclasses} || []}), + join('|', sort @{$options{roles} || []}), + ); + return $IMMORTAL_ANON_CLASSES{$cache_key} if exists $IMMORTAL_ANON_CLASSES{$cache_key}; + } my $package_name = $ANON_CLASS_PREFIX . ++$ANON_CLASS_SERIAL; - return $class->create( $package_name, %options ); + my $meta = $class->create( $package_name, anon_class_id => $ANON_CLASS_SERIAL, %options ); + + if($cache){ + $IMMORTAL_ANON_CLASSES{$cache_key} = $meta; + } + else{ + Mouse::Meta::Module::weaken_metaclass($package_name); + } + return $meta; + } + + sub is_anon_class{ + return exists $_[0]->{anon_class_id}; + } + + + sub DESTROY{ + my($self) = @_; + + my $serial_id = $self->{anon_class_id}; + + return if !$serial_id; + + my $stash = $self->namespace; + + @{$self->{sperclasses}} = (); + %{$stash} = (); + Mouse::Meta::Module::remove_metaclass_by_name($self->name); + + no strict 'refs'; + delete ${$ANON_CLASS_PREFIX}{ $serial_id . '::' }; + + return; } + } 1;