1 # This file was generated by tool/generate-mouse-tiny.pl from Mouse 0.43.
3 # ANY CHANGES MADE HERE WILL BE LOST!
5 # if regular Mouse is loaded, bail out
6 unless ($INC{'Mouse.pm'}) {
7 # tell Perl we already have all of the Mouse files loaded:
8 $INC{'Mouse.pm'} = __FILE__;
9 $INC{'Mouse/Util.pm'} = __FILE__;
10 $INC{'Mouse/Exporter.pm'} = __FILE__;
11 $INC{'Mouse/Object.pm'} = __FILE__;
12 $INC{'Mouse/PurePerl.pm'} = __FILE__;
13 $INC{'Mouse/Role.pm'} = __FILE__;
14 $INC{'Mouse/Meta/Module.pm'} = __FILE__;
15 $INC{'Mouse/Meta/Method.pm'} = __FILE__;
16 $INC{'Mouse/Meta/Role.pm'} = __FILE__;
17 $INC{'Mouse/Meta/Class.pm'} = __FILE__;
18 $INC{'Mouse/Meta/TypeConstraint.pm'} = __FILE__;
19 $INC{'Mouse/Meta/Attribute.pm'} = __FILE__;
20 $INC{'Mouse/Meta/Role/Method.pm'} = __FILE__;
21 $INC{'Mouse/Meta/Role/Composite.pm'} = __FILE__;
22 $INC{'Mouse/Meta/Method/Destructor.pm'} = __FILE__;
23 $INC{'Mouse/Meta/Method/Delegation.pm'} = __FILE__;
24 $INC{'Mouse/Meta/Method/Constructor.pm'} = __FILE__;
25 $INC{'Mouse/Meta/Method/Accessor.pm'} = __FILE__;
26 $INC{'Mouse/Util/MetaRole.pm'} = __FILE__;
27 $INC{'Mouse/Util/TypeConstraints.pm'} = __FILE__;
28 eval sprintf("#line %d %s\n", __LINE__, __FILE__) . <<'END_OF_TINY';
30 # and now their contents
32 BEGIN{ # lib/Mouse/PurePerl.pm
33 package Mouse::PurePerl;
43 use warnings FATAL => 'redefine'; # to avoid to load Mouse::PurePerl
50 return 0 if ref($class) || !defined($class) || !length($class);
52 # walk the symbol table tree to avoid autovififying
53 # \*{${main::}{"Foo::"}{"Bar::"}} == \*main::Foo::Bar::
56 foreach my $part (split('::', $class)) {
58 return 0 if !exists $pack->{$part};
60 my $entry = \$pack->{$part};
61 return 0 if ref($entry) ne 'GLOB';
62 $pack = *{$entry}{HASH};
65 return 0 if !%{$pack};
67 # check for $VERSION or @ISA
68 return 1 if exists $pack->{VERSION}
69 && defined *{$pack->{VERSION}}{SCALAR} && defined ${ $pack->{VERSION} };
70 return 1 if exists $pack->{ISA}
71 && defined *{$pack->{ISA}}{ARRAY} && @{ $pack->{ISA} } != 0;
73 # check for any method
74 foreach my $name( keys %{$pack} ) {
75 my $entry = \$pack->{$name};
76 return 1 if ref($entry) ne 'GLOB' || defined *{$entry}{CODE};
84 # taken from Sub::Identify
87 ref($coderef) or return;
89 my $cv = B::svref_2object($coderef);
90 $cv->isa('B::CV') or return;
93 $gv->isa('B::GV') or return;
95 return ($gv->STASH->NAME, $gv->NAME);
101 my $cv = B::svref_2object($coderef);
102 $cv->isa('B::CV') or return '';
105 $gv->isa('B::GV') or return '';
107 return $gv->STASH->NAME;
111 my($package, $name) = @_;
114 use warnings FATAL => 'uninitialized';
115 return *{$package . '::' . $name}{CODE};
118 sub generate_isa_predicate_for {
119 my($for_class, $name) = @_;
121 my $predicate = sub{ Scalar::Util::blessed($_[0]) && $_[0]->isa($for_class) };
125 *{ caller() . '::' . $name } = $predicate;
134 Mouse::Util::TypeConstraints;
136 use Scalar::Util qw(blessed looks_like_number openhandle);
141 sub Bool { $_[0] ? $_[0] eq '1' : 1 }
142 sub Undef { !defined($_[0]) }
143 sub Defined { defined($_[0]) }
144 sub Value { defined($_[0]) && !ref($_[0]) }
145 sub Num { !ref($_[0]) && looks_like_number($_[0]) }
146 sub Int { defined($_[0]) && !ref($_[0]) && $_[0] =~ /^-?[0-9]+$/ }
147 sub Str { defined($_[0]) && !ref($_[0]) }
149 sub Ref { ref($_[0]) }
150 sub ScalarRef { ref($_[0]) eq 'SCALAR' }
151 sub ArrayRef { ref($_[0]) eq 'ARRAY' }
152 sub HashRef { ref($_[0]) eq 'HASH' }
153 sub CodeRef { ref($_[0]) eq 'CODE' }
154 sub RegexpRef { ref($_[0]) eq 'Regexp' }
155 sub GlobRef { ref($_[0]) eq 'GLOB' }
158 openhandle($_[0]) || (blessed($_[0]) && $_[0]->isa("IO::Handle"))
161 sub Object { blessed($_[0]) && blessed($_[0]) ne 'Regexp' }
163 sub ClassName { Mouse::Util::is_class_loaded($_[0]) }
164 sub RoleName { (Mouse::Util::class_of($_[0]) || return 0)->isa('Mouse::Meta::Role') }
166 sub _parameterize_ArrayRef_for {
167 my($type_parameter) = @_;
168 my $check = $type_parameter->_compiled_type_constraint;
171 foreach my $value (@{$_}) {
172 return undef unless $check->($value);
178 sub _parameterize_HashRef_for {
179 my($type_parameter) = @_;
180 my $check = $type_parameter->_compiled_type_constraint;
183 foreach my $value(values %{$_}){
184 return undef unless $check->($value);
190 # 'Maybe' type accepts 'Any', so it requires parameters
191 sub _parameterize_Maybe_for {
192 my($type_parameter) = @_;
193 my $check = $type_parameter->_compiled_type_constraint;
196 return !defined($_) || $check->($_);
205 sub name { $_[0]->{package} }
207 sub _method_map { $_[0]->{methods} }
208 sub _attribute_map{ $_[0]->{attributes} }
211 my $name = $_[0]->{package};
213 return \%{ $name . '::' };
217 my($self, $name, $code) = @_;
220 $self->throw_error('You must pass a defined name');
223 $self->throw_error('You must pass a defined code');
226 if(ref($code) ne 'CODE'){
227 $code = \&{$code}; # coerce
230 $self->{methods}->{$name} = $code; # Moose stores meta object here.
232 my $pkg = $self->name;
234 no warnings 'redefine', 'once';
235 *{ $pkg . '::' . $name } = $code;
242 sub method_metaclass { $_[0]->{method_metaclass} || 'Mouse::Meta::Method' }
243 sub attribute_metaclass { $_[0]->{attribute_metaclass} || 'Mouse::Meta::Attribute' }
245 sub constructor_class { $_[0]->{constructor_class} || 'Mouse::Meta::Method::Constructor' }
246 sub destructor_class { $_[0]->{destructor_class} || 'Mouse::Meta::Method::Destructor' }
249 return exists $_[0]->{anon_serial_id};
252 sub roles { $_[0]->{roles} }
254 sub linearized_isa { @{ get_linear_isa($_[0]->{package}) } }
256 sub get_all_attributes {
258 my %attrs = map { %{ $self->initialize($_)->{attributes} } } reverse $self->linearized_isa;
259 return values %attrs;
264 my %args = (@_ == 1 ? %{$_[0]} : @_);
266 my $object = bless {}, $self->name;
268 $self->_initialize_object($object, \%args);
272 sub _initialize_object{
273 my($self, $object, $args, $ignore_triggers) = @_;
277 foreach my $attribute ($self->get_all_attributes) {
278 my $init_arg = $attribute->init_arg;
279 my $slot = $attribute->name;
281 if (defined($init_arg) && exists($args->{$init_arg})) {
282 $object->{$slot} = $attribute->_coerce_and_verify($args->{$init_arg}, $object);
284 weaken($object->{$slot})
285 if ref($object->{$slot}) && $attribute->is_weak_ref;
287 if ($attribute->has_trigger) {
288 push @triggers_queue, [ $attribute->trigger, $object->{$slot} ];
292 if ($attribute->has_default || $attribute->has_builder) {
293 if (!$attribute->is_lazy) {
294 my $default = $attribute->default;
295 my $builder = $attribute->builder;
296 my $value = $builder ? $object->$builder()
297 : ref($default) eq 'CODE' ? $object->$default()
300 $object->{$slot} = $attribute->_coerce_and_verify($value, $object);
302 weaken($object->{$slot})
303 if ref($object->{$slot}) && $attribute->is_weak_ref;
306 elsif($attribute->is_required) {
307 $self->throw_error("Attribute (".$attribute->name.") is required");
312 if(!$ignore_triggers){
313 foreach my $trigger_and_value(@triggers_queue){
314 my($trigger, $value) = @{$trigger_and_value};
315 $trigger->($object, $value);
319 if($self->is_anon_class){
320 $object->{__METACLASS__} = $self;
330 sub method_metaclass{ $_[0]->{method_metaclass} || 'Mouse::Meta::Role::Method' }
333 return exists $_[0]->{anon_serial_id};
336 sub get_roles { $_[0]->{roles} }
339 Mouse::Meta::Attribute;
341 require Mouse::Meta::Method::Accessor;
343 sub accessor_metaclass{ $_[0]->{accessor_metaclass} || 'Mouse::Meta::Method::Accessor' }
347 sub name { $_[0]->{name} }
348 sub associated_class { $_[0]->{associated_class} }
350 sub accessor { $_[0]->{accessor} }
351 sub reader { $_[0]->{reader} }
352 sub writer { $_[0]->{writer} }
353 sub predicate { $_[0]->{predicate} }
354 sub clearer { $_[0]->{clearer} }
355 sub handles { $_[0]->{handles} }
357 sub _is_metadata { $_[0]->{is} }
358 sub is_required { $_[0]->{required} }
359 sub default { $_[0]->{default} }
360 sub is_lazy { $_[0]->{lazy} }
361 sub is_lazy_build { $_[0]->{lazy_build} }
362 sub is_weak_ref { $_[0]->{weak_ref} }
363 sub init_arg { $_[0]->{init_arg} }
364 sub type_constraint { $_[0]->{type_constraint} }
366 sub trigger { $_[0]->{trigger} }
367 sub builder { $_[0]->{builder} }
368 sub should_auto_deref { $_[0]->{auto_deref} }
369 sub should_coerce { $_[0]->{coerce} }
371 sub documentation { $_[0]->{documentation} }
375 sub has_accessor { exists $_[0]->{accessor} }
376 sub has_reader { exists $_[0]->{reader} }
377 sub has_writer { exists $_[0]->{writer} }
378 sub has_predicate { exists $_[0]->{predicate} }
379 sub has_clearer { exists $_[0]->{clearer} }
380 sub has_handles { exists $_[0]->{handles} }
382 sub has_default { exists $_[0]->{default} }
383 sub has_type_constraint { exists $_[0]->{type_constraint} }
384 sub has_trigger { exists $_[0]->{trigger} }
385 sub has_builder { exists $_[0]->{builder} }
387 sub has_documentation { exists $_[0]->{documentation} }
390 Mouse::Meta::TypeConstraint;
392 sub name { $_[0]->{name} }
393 sub parent { $_[0]->{parent} }
394 sub message { $_[0]->{message} }
396 sub _compiled_type_constraint{ $_[0]->{compiled_type_constraint} }
398 sub _compiled_type_coercion { $_[0]->{_compiled_type_coercion} }
400 sub has_coercion{ exists $_[0]->{_compiled_type_coercion} }
403 sub compile_type_constraint{
408 for(my $parent = $self->{parent}; defined $parent; $parent = $parent->{parent}){
409 if($parent->{hand_optimized_type_constraint}){
410 unshift @checks, $parent->{hand_optimized_type_constraint};
411 last; # a hand optimized constraint must include all the parents
413 elsif($parent->{constraint}){
414 unshift @checks, $parent->{constraint};
419 if($self->{constraint}){
420 push @checks, $self->{constraint};
423 if($self->{type_constraints}){ # Union
424 my @types = map{ $_->{compiled_type_constraint} } @{ $self->{type_constraints} };
426 foreach my $c(@types){
427 return 1 if $c->($_[0]);
434 $self->{compiled_type_constraint} = \&Mouse::Util::TypeConstraints::Any;
437 $self->{compiled_type_constraint} = sub{
440 foreach my $c(@checks){
441 return undef if !$c->(@args);
456 if (scalar @_ == 1) {
457 (ref($_[0]) eq 'HASH')
458 || $class->meta->throw_error("Single parameters to new() must be a HASH ref");
470 $class->meta->throw_error('Cannot call new() on an instance') if ref $class;
472 my $args = $class->BUILDARGS(@_);
474 my $meta = Mouse::Meta::Class->initialize($class);
475 my $self = $meta->new_object($args);
478 if( $self->can('BUILD') ) {
479 for my $class (reverse $meta->linearized_isa) {
480 my $build = Mouse::Util::get_code_ref($class, 'BUILD')
483 $self->$build($args);
493 return unless $self->can('DEMOLISH'); # short circuit
503 # We cannot count on being able to retrieve a previously made
504 # metaclass, _or_ being able to make a new one during global
505 # destruction. However, we should still be able to use mro at
506 # that time (at least tests suggest so ;)
508 foreach my $class (@{ Mouse::Util::get_linear_isa(ref $self) }) {
509 my $demolish = Mouse::Util::get_code_ref($class, 'DEMOLISH')
519 die $e if $e; # rethrow
523 BEGIN{ # lib/Mouse/Exporter.pm
524 package Mouse::Exporter;
528 use Carp qw(confess);
532 use constant _strict_bits => strict::bits(qw(subs refs vars));
534 # it must be "require", because Mouse::Util depends on Mouse::Exporter,
535 # which depends on Mouse::Util::import()
539 $^H |= _strict_bits; # strict->import;
540 ${^WARNING_BITS} |= $warnings::Bits{all}; # warnings->import;
545 sub setup_import_methods{
546 my($class, %args) = @_;
548 my $exporting_package = $args{exporting_package} ||= caller();
550 my($import, $unimport) = $class->build_import_methods(%args);
554 *{$exporting_package . '::import'} = $import;
555 *{$exporting_package . '::unimport'} = $unimport;
557 # for backward compatibility
558 *{$exporting_package . '::export_to_level'} = sub{
559 my($package, $level, undef, @args) = @_; # the third argument is redundant
560 $package->import({ into_level => $level + 1 }, @args);
562 *{$exporting_package . '::export'} = sub{
563 my($package, $into, @args) = @_;
564 $package->import({ into => $into }, @args);
569 sub build_import_methods{
570 my($class, %args) = @_;
572 my $exporting_package = $args{exporting_package} ||= caller();
574 $SPEC{$exporting_package} = \%args;
580 my @stack = ($exporting_package);
582 while(my $current = shift @stack){
583 push @export_from, $current;
585 my $also = $SPEC{$current}{also} or next;
586 push @stack, grep{ !$seen{$_}++ } ref($also) ? @{ $also } : $also;
590 @export_from = ($exporting_package);
598 my @init_meta_methods;
600 foreach my $package(@export_from){
601 my $spec = $SPEC{$package} or next;
603 if(my $as_is = $spec->{as_is}){
604 foreach my $thingy (@{$as_is}){
605 my($code_package, $code_name, $code);
609 ($code_package, $code_name) = Mouse::Util::get_code_info($code);
613 $code_package = $package;
614 $code_name = $thingy;
615 $code = \&{ $code_package . '::' . $code_name };
618 push @all, $code_name;
619 $exports{$code_name} = $code;
620 if($code_package eq $package){
621 push @removables, $code_name;
626 if(my $init_meta = $package->can('init_meta')){
627 if(!grep{ $_ == $init_meta } @init_meta_methods){
628 push @init_meta_methods, $init_meta;
632 $args{EXPORTS} = \%exports;
633 $args{REMOVABLES} = \@removables;
635 $args{groups}{all} ||= \@all;
637 if(my $default_list = $args{groups}{default}){
639 foreach my $keyword(@{$default_list}){
640 $default{$keyword} = $exports{$keyword}
641 || confess(qq{The $exporting_package package does not export "$keyword"});
643 $args{DEFAULT} = \%default;
646 $args{groups}{default} ||= \@all;
647 $args{DEFAULT} = $args{EXPORTS};
650 if(@init_meta_methods){
651 $args{INIT_META} = \@init_meta_methods;
655 return (\&do_import, \&do_unimport);
659 # the entity of general import()
661 my($package, @args) = @_;
663 my $spec = $SPEC{$package}
664 || confess("The package $package package does not use Mouse::Exporter");
666 my $into = _get_caller_package(ref($args[0]) ? shift @args : undef);
672 my $arg = shift @args;
674 if($arg eq 'traits'){
675 push @traits, ref($args[0]) ? @{shift(@args)} : shift(@args);
678 Mouse::Util::not_supported("-$arg");
681 elsif($arg =~ s/^://){
682 my $group = $spec->{groups}{$arg}
683 || confess(qq{The $package package does not export the group "$arg"});
684 push @exports, @{$group};
691 $^H |= _strict_bits; # strict->import;
692 ${^WARNING_BITS} |= $warnings::Bits{all}; # warnings->import;
694 if($spec->{INIT_META}){
696 foreach my $init_meta(@{$spec->{INIT_META}}){
697 $meta = $into->$init_meta(for_class => $into);
701 my $type = (split /::/, ref $meta)[-1]; # e.g. "Class" for "My::Meta::Class"
705 : Mouse::Util::resolve_metaclass_alias($type => $_, trait => 1)
708 require Mouse::Util::MetaRole;
709 Mouse::Util::MetaRole::apply_metaclass_roles(
711 metaclass_roles => \@traits,
716 Carp::confess("Cannot provide traits when $package does not have an init_meta() method");
720 foreach my $keyword(@exports){
722 *{$into.'::'.$keyword} = $spec->{EXPORTS}{$keyword}
723 || confess(qq{The $package package does not export "$keyword"});
727 my $default = $spec->{DEFAULT};
728 while(my($keyword, $code) = each %{$default}){
730 *{$into.'::'.$keyword} = $code;
736 # the entity of general unimport()
738 my($package, $arg) = @_;
740 my $spec = $SPEC{$package}
741 || confess("The package $package does not use Mouse::Exporter");
743 my $from = _get_caller_package($arg);
750 for my $keyword (@{ $spec->{REMOVABLES} }) {
751 my $gv = \$stash->{$keyword};
752 if(ref($gv) eq 'GLOB' && *{$gv}{CODE} == $spec->{EXPORTS}{$keyword}){ # make sure it is from us
753 delete $stash->{$keyword};
759 # 1 extra level because it's called by import so there's a layer
\r
763 sub _get_caller_package {
767 return defined($arg->{into}) ? $arg->{into}
768 : defined($arg->{into_level}) ? scalar caller(_LEVEL + $arg->{into_level})
769 : scalar caller(_LEVEL);
772 return scalar caller(_LEVEL);
779 BEGIN{ # lib/Mouse/Util.pm
781 use Mouse::Exporter; # enables strict and warnings
783 sub get_linear_isa($;$); # must be here
786 # This is used in Mouse::PurePerl
787 Mouse::Exporter->setup_import_methods(
791 resolve_metaclass_alias
809 default => [], # export no functions by default
811 # The ':meta' group is 'use metaclass' for Mouse
812 meta => [qw(does meta dump)],
817 # Because Mouse::Util is loaded first in all the Mouse sub-modules,
818 # XS loader is placed here, not in Mouse.pm.
820 our $VERSION = '0.43';
822 my $xs = !(exists $INC{'Mouse/PurePerl.pm'} || $ENV{MOUSE_PUREPERL});
825 # XXX: XSLoader tries to get the object path from caller's file name
826 # $hack_mouse_file fools its mechanism
828 (my $hack_mouse_file = __FILE__) =~ s/.Util//; # .../Mouse/Util.pm -> .../Mouse.pm
829 $xs = eval sprintf("#line %d %s\n", __LINE__, $hack_mouse_file) . q{
831 XSLoader::load('Mouse', $VERSION);
832 Mouse::Util->import({ into => 'Mouse::Meta::Method::Constructor::XS' }, ':meta');
833 Mouse::Util->import({ into => 'Mouse::Meta::Method::Destructor::XS' }, ':meta');
834 Mouse::Util->import({ into => 'Mouse::Meta::Method::Accessor::XS' }, ':meta');
841 require 'Mouse/PurePerl.pm'; # we don't want to create its namespace
844 *MOUSE_XS = sub(){ $xs };
850 use constant _MOUSE_VERBOSE => !!$ENV{MOUSE_VERBOSE};
852 # aliases as public APIs
853 # it must be 'require', not 'use', because Mouse::Meta::Module depends on Mouse::Util
854 require Mouse::Meta::Module; # for the entities of metaclass cache utilities
857 *class_of = \&Mouse::Meta::Module::_class_of;
858 *get_metaclass_by_name = \&Mouse::Meta::Module::_get_metaclass_by_name;
859 *get_all_metaclass_instances = \&Mouse::Meta::Module::_get_all_metaclass_instances;
860 *get_all_metaclass_names = \&Mouse::Meta::Module::_get_all_metaclass_names;
863 generate_isa_predicate_for('Mouse::Meta::TypeConstraint' => 'is_a_type_constraint');
864 generate_isa_predicate_for('Mouse::Meta::Class' => 'is_a_metaclass');
865 generate_isa_predicate_for('Mouse::Meta::Role' => 'is_a_metarole');
868 our $in_global_destruction = 0;
869 END{ $in_global_destruction = 1 }
871 # Moose::Util compatible utilities
874 return class_of( $_[0] );
878 my ($class_or_obj, $role_name) = @_;
880 my $meta = class_of($class_or_obj);
883 || ($meta || 'Mouse::Meta::Class')->throw_error("You must supply a role name to does()");
885 return defined($meta) && $meta->does_role($role_name);
890 if ($] >= 5.009_005) {
892 $get_linear_isa = \&mro::get_linear_isa;
894 # VVVVV CODE TAKEN FROM MRO::COMPAT VVVVV
895 my $_get_linear_isa_dfs; # this recurses so it isn't pretty
896 $_get_linear_isa_dfs = sub {
899 my @lin = ($classname);
903 foreach my $parent (@{"$classname\::ISA"}) {
904 my $plin = $_get_linear_isa_dfs->($parent);
905 foreach my $p(@$plin) {
906 next if exists $stored{$p};
913 # ^^^^^ CODE TAKEN FROM MRO::COMPAT ^^^^^
915 eval{ require Class::C3 };
917 # MRO::Compat::__get_linear_isa has no prototype, so
918 # we define a prototyped version for compatibility with core's
919 # See also MRO::Compat::__get_linear_isa.
920 $get_linear_isa = sub ($;$){
921 my($classname, $type) = @_;
922 package # hide from PAUSE
926 $type = exists $MRO{$classname} ? 'c3' : 'dfs';
929 ? [calculateMRO($classname)]
930 : $_get_linear_isa_dfs->($classname);
\r
934 *get_linear_isa = $get_linear_isa;
938 # taken from Mouse::Util (0.90)
942 sub resolve_metaclass_alias {
943 my ( $type, $metaclass_name, %options ) = @_;
945 my $cache_key = $type . q{ } . ( $options{trait} ? '-Trait' : '' );
947 return $cache{$cache_key}{$metaclass_name} ||= do{
949 my $possible_full_name = join '::',
950 'Mouse::Meta', $type, 'Custom', ($options{trait} ? 'Trait' : ()), $metaclass_name
953 my $loaded_class = load_first_existing_class(
958 $loaded_class->can('register_implementation')
959 ? $loaded_class->register_implementation
965 # Utilities from Class::MOP
968 sub get_code_package;
970 # taken from Class/MOP.pm
971 sub is_valid_class_name {
974 return 0 if ref($class);
975 return 0 unless defined($class);
977 return 1 if $class =~ /\A \w+ (?: :: \w+ )* \z/xms;
982 # taken from Class/MOP.pm
983 sub load_first_existing_class {
988 for my $class (@classes) {
989 my $e = _try_load_one_class($class);
992 $exceptions{$class} = $e;
1003 sprintf( "Could not load class (%s) because : %s",
1004 $_, $exceptions{$_} )
1009 # taken from Class/MOP.pm
1010 my %is_class_loaded_cache;
1011 sub _try_load_one_class {
1014 unless ( is_valid_class_name($class) ) {
1015 my $display = defined($class) ? $class : 'undef';
1016 Carp::confess "Invalid class name ($display)";
1019 return undef if $is_class_loaded_cache{$class} ||= is_class_loaded($class);
1021 my $file = $class . '.pm';
1026 eval { require($file) };
1034 my $e = _try_load_one_class($class);
1035 Carp::confess "Could not load class ($class) because : $e" if $e;
1040 sub is_class_loaded;
1042 sub apply_all_roles {
1043 my $applicant = Scalar::Util::blessed($_[0])
1045 : Mouse::Meta::Class->initialize(shift); # class or role name
1049 # Basis of Data::OptList
1050 my $max = scalar(@_);
1051 for (my $i = 0; $i < $max ; $i++) {
1052 if ($i + 1 < $max && ref($_[$i + 1])) {
1053 push @roles, [ $_[$i] => $_[++$i] ];
1055 push @roles, [ $_[$i] => undef ];
1057 my $role_name = $roles[-1][0];
1058 load_class($role_name);
1060 is_a_metarole( get_metaclass_by_name($role_name) )
1061 || $applicant->meta->throw_error("You can only consume roles, $role_name is not a Mouse role");
1064 if ( scalar @roles == 1 ) {
1065 my ( $role_name, $params ) = @{ $roles[0] };
1066 get_metaclass_by_name($role_name)->apply( $applicant, defined $params ? $params : () );
1069 Mouse::Meta::Role->combine(@roles)->apply($applicant);
1074 # taken from Moose::Util 0.90
1076 return $_[0] if @_ == 1;
1078 my @items = sort @_;
1080 return "$items[0] and $items[1]" if @items == 2;
1082 my $tail = pop @items;
1084 return join q{, }, @items, "and $tail";
1092 $feature ||= ( caller(1) )[3]; # subroutine name
1094 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
1095 Carp::confess("Mouse does not currently support $feature");
1098 # general meta() method
1100 return Mouse::Meta::Class->initialize(ref($_[0]) || $_[0]);
1103 # general dump() method
1105 my($self, $maxdepth) = @_;
1107 require 'Data/Dumper.pm'; # we don't want to create its namespace
1108 my $dd = Data::Dumper->new([$self]);
1109 $dd->Maxdepth(defined($maxdepth) ? $maxdepth : 2);
1114 # general does() method
1116 *does = \&does_role; # alias
1119 BEGIN{ # lib/Mouse/Meta/TypeConstraint.pm
1120 package Mouse::Meta::TypeConstraint;
1121 use Mouse::Util qw(:meta); # enables strict and warnings
1124 'bool' => sub { 1 }, # always true
1126 '""' => sub { $_[0]->name }, # stringify to tc name
1128 '|' => sub { # or-combination
1129 require Mouse::Util::TypeConstraints;
1130 return Mouse::Util::TypeConstraints::find_or_parse_type_constraint(
1140 my($class, %args) = @_;
1142 $args{name} = '__ANON__' if !defined $args{name};
1144 my $check = delete $args{optimized};
1146 if($args{_compiled_type_constraint}){
1147 Carp::cluck("'_compiled_type_constraint' has been deprecated, use 'optimized' instead")
1148 if Mouse::Util::_MOUSE_VERBOSE;
1150 $check = $args{_compiled_type_constraint};
1154 $args{hand_optimized_type_constraint} = $check;
1155 $args{compiled_type_constraint} = $check;
1158 $check = $args{constraint};
1160 if(defined($check) && ref($check) ne 'CODE'){
1161 Carp::confess("Constraint for $args{name} is not a CODE reference");
1164 $args{package_defined_in} ||= caller;
1166 my $self = bless \%args, $class;
1167 $self->compile_type_constraint() if !$self->{hand_optimized_type_constraint};
1169 if($self->{type_constraints}){ # Union
1171 foreach my $type(@{$self->{type_constraints}}){
1172 if($type->has_coercion){
1173 push @coercions, $type;
1177 $self->{_compiled_type_coercion} = sub {
1179 foreach my $type(@coercions){
1180 my $value = $type->coerce($thing);
1181 return $value if $self->check($value);
1191 sub create_child_type{
1194 return ref($self)->new(
1195 # a child inherits its parent's attributes
1198 # but does not inherit 'compiled_type_constraint' and 'hand_optimized_type_constraint'
1199 compiled_type_constraint => undef,
1200 hand_optimized_type_constraint => undef,
1202 # and is given child-specific args, of course.
1210 sub _add_type_coercions{
1213 my $coercions = ($self->{_coercion_map} ||= []);
1214 my %has = map{ $_->[0] => undef } @{$coercions};
1216 for(my $i = 0; $i < @_; $i++){
1218 my $action = $_[++$i];
1220 if(exists $has{$from}){
1221 Carp::confess("A coercion action already exists for '$from'");
1224 my $type = Mouse::Util::TypeConstraints::find_or_parse_type_constraint($from)
1225 or Carp::confess("Could not find the type constraint ($from) to coerce from");
1227 push @{$coercions}, [ $type => $action ];
1231 if(exists $self->{type_constraints}){ # union type
1232 Carp::confess("Cannot add additional type coercions to Union types");
1235 $self->{_compiled_type_coercion} = sub {
1237 foreach my $pair (@{$coercions}) {
\r
1238 #my ($constraint, $converter) = @$pair;
\r
1239 if ($pair->[0]->check($thing)) {
\r
1241 return $pair->[1]->($thing);
1252 return $self->_compiled_type_constraint->(@_);
1258 return $_[0] if $self->_compiled_type_constraint->(@_);
1260 my $coercion = $self->_compiled_type_coercion;
1261 return $coercion ? $coercion->(@_) : $_[0];
1265 my ($self, $value) = @_;
1266 if ( my $msg = $self->message ) {
1268 return $msg->($value);
1271 $value = ( defined $value ? overload::StrVal($value) : 'undef' );
1272 return "Validation failed for '$self' failed with value $value";
1277 my($self, $other) = @_;
1279 # ->is_a_type_of('__ANON__') is always false
1280 return 0 if !ref($other) && $other eq '__ANON__';
1282 (my $other_name = $other) =~ s/\s+//g;
1284 return 1 if $self->name eq $other_name;
1286 if(exists $self->{type_constraints}){ # union
1287 foreach my $type(@{$self->{type_constraints}}){
1288 return 1 if $type->name eq $other_name;
1292 for(my $parent = $self->parent; defined $parent; $parent = $parent->parent){
1293 return 1 if $parent->name eq $other_name;
1299 # See also Moose::Meta::TypeConstraint::Parameterizable
1301 my($self, $param, $name) = @_;
1304 require Mouse::Util::TypeConstraints;
1305 $param = Mouse::Util::TypeConstraints::find_or_create_isa_type_constraint($param);
1308 $name ||= sprintf '%s[%s]', $self->name, $param->name;
1310 my $generator = $self->{constraint_generator}
1311 || Carp::confess("The $name constraint cannot be used, because $param doesn't subtype from a parameterizable type");
1313 return Mouse::Meta::TypeConstraint->new(
1316 parameter => $param,
1317 constraint => $generator->($param), # must be 'constraint', not 'optimized'
1319 type => 'Parameterized',
1324 BEGIN{ # lib/Mouse/Util/TypeConstraints.pm
1325 package Mouse::Util::TypeConstraints;
1326 use Mouse::Util qw(does_role not_supported); # enables strict and warnings
1328 use Carp qw(confess);
1329 use Scalar::Util ();
1331 use Mouse::Meta::TypeConstraint;
1332 use Mouse::Exporter;
1334 Mouse::Exporter->setup_import_methods(
1336 as where message optimize_as
1338 type subtype coerce class_type role_type enum
1339 find_type_constraint
1345 sub as ($) { (as => $_[0]) }
1346 sub where (&) { (where => $_[0]) }
1347 sub message (&) { (message => $_[0]) }
1348 sub optimize_as (&) { (optimize_as => $_[0]) }
1351 sub via (&) { $_[0] }
1355 Any => undef, # null check
1356 Item => undef, # null check
1357 Maybe => undef, # null check
1361 Defined => \&Defined,
1368 ScalarRef => \&ScalarRef,
1369 ArrayRef => \&ArrayRef,
1370 HashRef => \&HashRef,
1371 CodeRef => \&CodeRef,
1372 RegexpRef => \&RegexpRef,
1373 GlobRef => \&GlobRef,
1375 FileHandle => \&FileHandle,
1379 ClassName => \&ClassName,
1380 RoleName => \&RoleName,
1383 while (my ($name, $code) = each %builtins) {
1384 $TYPE{$name} = Mouse::Meta::TypeConstraint->new(
1390 sub optimized_constraints { # DEPRECATED
1391 Carp::cluck('optimized_constraints() has been deprecated');
1395 my @builtins = keys %TYPE;
1396 sub list_all_builtin_type_constraints { @builtins }
1398 sub list_all_type_constraints { keys %TYPE }
1407 if(@_ == 1 && ref $_[0]){ # @_ : { name => $name, where => ... }
1410 elsif(@_ == 2 && ref $_[1]){ # @_ : $name => { where => ... }
1414 elsif(@_ % 2){ # @_ : $name => ( where => ... )
1415 ($name, %args) = @_;
1417 else{ # @_ : (name => $name, where => ...)
1422 if(!defined($name = $args{name})){
1427 $args{name} = $name;
1429 if($mode eq 'subtype'){
1430 $parent = delete $args{as};
1432 $parent = delete $args{name};
1437 my $package_defined_in = $args{package_defined_in} ||= caller(1);
1439 my $existing = $TYPE{$name};
1440 if($existing && $existing->{package_defined_in} ne $package_defined_in){
1441 confess("The type constraint '$name' has already been created in "
1442 . "$existing->{package_defined_in} and cannot be created again in $package_defined_in");
1445 $args{constraint} = delete $args{where} if exists $args{where};
1446 $args{optimized} = delete $args{optimized_as} if exists $args{optimized_as};
1449 if($mode eq 'subtype'){
1450 $constraint = find_or_create_isa_type_constraint($parent)->create_child_type(%args);
1453 $constraint = Mouse::Meta::TypeConstraint->new(%args);
1456 return $TYPE{$name} = $constraint;
1460 return _create_type('type', @_);
1464 return _create_type('subtype', @_);
1468 my $type_name = shift;
1470 my $type = find_type_constraint($type_name)
1471 or confess("Cannot find type '$type_name', perhaps you forgot to load it.");
1473 $type->_add_type_coercions(@_);
1478 my($name, $options) = @_;
1479 my $class = $options->{class} || $name;
1480 return _create_type 'subtype', $name => (
1482 optimized_as => Mouse::Util::generate_isa_predicate_for($class),
1489 my($name, $options) = @_;
1490 my $role = $options->{role} || $name;
1491 return _create_type 'subtype', $name => (
1493 optimized_as => sub { Scalar::Util::blessed($_[0]) && does_role($_[0], $role) },
1499 sub typecast_constraints { # DEPRECATED
1500 my($class, $pkg, $type, $value) = @_;
1501 Carp::croak("wrong arguments count") unless @_ == 4;
1503 Carp::cluck("typecast_constraints() has been deprecated, which was an internal utility anyway");
1505 return $type->coerce($value);
1511 # enum ['small', 'medium', 'large']
1512 if (ref($_[0]) eq 'ARRAY') {
1513 %valid = map{ $_ => undef } @{ $_[0] };
1514 $name = sprintf '(%s)', join '|', sort @{$_[0]};
1516 # enum size => 'small', 'medium', 'large'
1519 %valid = map{ $_ => undef } @_;
1521 return _create_type 'type', $name => (
1522 optimized_as => sub{ defined($_[0]) && !ref($_[0]) && exists $valid{$_[0]} },
1528 sub _find_or_create_regular_type{
1531 return $TYPE{$spec} if exists $TYPE{$spec};
1533 my $meta = Mouse::Util::get_metaclass_by_name($spec)
1536 if(Mouse::Util::is_a_metarole($meta)){
1537 return role_type($spec);
1540 return class_type($spec);
1544 $TYPE{ArrayRef}{constraint_generator} = \&_parameterize_ArrayRef_for;
1545 $TYPE{HashRef}{constraint_generator} = \&_parameterize_HashRef_for;
1546 $TYPE{Maybe}{constraint_generator} = \&_parameterize_Maybe_for;
1548 sub _find_or_create_parameterized_type{
1549 my($base, $param) = @_;
1551 my $name = sprintf '%s[%s]', $base->name, $param->name;
1553 $TYPE{$name} ||= $base->parameterize($param, $name);
1556 sub _find_or_create_union_type{
1557 my @types = sort map{ $_->{type_constraints} ? @{$_->{type_constraints}} : $_ } @_;
1559 my $name = join '|', @types;
1561 $TYPE{$name} ||= Mouse::Meta::TypeConstraint->new(
1563 type_constraints => \@types,
1571 my($spec, $start) = @_;
1576 my $len = length $spec;
1579 for($i = $start; $i < $len; $i++){
1580 my $char = substr($spec, $i, 1);
1583 my $base = _find_or_create_regular_type( substr($spec, $start, $i - $start) )
1586 ($i, $subtype) = _parse_type($spec, $i+1)
1588 $start = $i+1; # reset
1590 push @list, _find_or_create_parameterized_type($base => $subtype);
1592 elsif($char eq ']'){
1596 elsif($char eq '|'){
1597 my $type = _find_or_create_regular_type( substr($spec, $start, $i - $start) );
1600 # XXX: Mouse creates a new class type, but Moose does not.
1601 $type = class_type( substr($spec, $start, $i - $start) );
1606 ($i, $subtype) = _parse_type($spec, $i+1)
1609 $start = $i+1; # reset
1611 push @list, $subtype;
1615 my $type = _find_or_create_regular_type( substr $spec, $start, $i - $start );
1620 elsif($start != 0) {
1622 # create a new class type
1623 push @list, class_type( substr $spec, $start, $i - $start );
1631 return ($len, $list[0]);
1634 return ($len, _find_or_create_union_type(@list));
1639 sub find_type_constraint {
1641 return $spec if Mouse::Util::is_a_type_constraint($spec);
1644 return $TYPE{$spec};
1647 sub find_or_parse_type_constraint {
1649 return $spec if Mouse::Util::is_a_type_constraint($spec);
1652 return $TYPE{$spec} || do{
1653 my($pos, $type) = _parse_type($spec, 0);
1658 sub find_or_create_does_type_constraint{
1659 # XXX: Moose does not register a new role_type, but Mouse does.
1660 return find_or_parse_type_constraint(@_) || role_type(@_);
1663 sub find_or_create_isa_type_constraint {
1664 # XXX: Moose does not register a new class_type, but Mouse does.
1665 return find_or_parse_type_constraint(@_) || class_type(@_);
1669 BEGIN{ # lib/Mouse.pm
1673 use Mouse::Exporter; # enables strict and warnings
1675 our $VERSION = '0.43';
1677 use Carp qw(confess);
1678 use Scalar::Util qw(blessed);
1680 use Mouse::Util qw(load_class is_class_loaded get_code_package not_supported);
1682 use Mouse::Meta::Module;
1683 use Mouse::Meta::Class;
1684 use Mouse::Meta::Role;
1685 use Mouse::Meta::Attribute;
1687 use Mouse::Util::TypeConstraints ();
1689 Mouse::Exporter->setup_import_methods(
1697 \&Scalar::Util::blessed,
1704 Mouse::Meta::Class->initialize(scalar caller)->superclasses(@_);
1709 Mouse::Util::apply_all_roles(scalar(caller), @_);
1714 my $meta = Mouse::Meta::Class->initialize(scalar caller);
1717 $meta->throw_error(q{Usage: has 'name' => ( key => value, ... )})
1718 if @_ % 2; # odd number of arguments
1720 if(ref $name){ # has [qw(foo bar)] => (...)
1722 $meta->add_attribute($_ => @_);
1725 else{ # has foo => (...)
1726 $meta->add_attribute($name => @_);
1732 my $meta = Mouse::Meta::Class->initialize(scalar caller);
1737 $meta->add_before_method_modifier($_ => $code);
1743 my $meta = Mouse::Meta::Class->initialize(scalar caller);
1748 $meta->add_after_method_modifier($_ => $code);
1754 my $meta = Mouse::Meta::Class->initialize(scalar caller);
1759 $meta->add_around_method_modifier($_ => $code);
1769 # This check avoids a recursion loop - see
1770 # t/100_bugs/020_super_recursion.t
1771 return if defined $SUPER_PACKAGE && $SUPER_PACKAGE ne caller();
1772 return if !defined $SUPER_BODY;
1773 $SUPER_BODY->(@SUPER_ARGS);
1777 # my($name, $method) = @_;
1778 Mouse::Meta::Class->initialize(scalar caller)->add_override_method_modifier(@_);
1786 if ( my $body = $INNER_BODY{$pkg} ) {
1787 my $args = $INNER_ARGS{$pkg};
1788 local $INNER_ARGS{$pkg};
1789 local $INNER_BODY{$pkg};
1790 return $body->(@{$args});
1798 #my($name, $method) = @_;
1799 Mouse::Meta::Class->initialize(scalar caller)->add_augment_method_modifier(@_);
1807 my $class = $args{for_class}
1808 or confess("Cannot call init_meta without specifying a for_class");
1810 my $base_class = $args{base_class} || 'Mouse::Object';
1811 my $metaclass = $args{metaclass} || 'Mouse::Meta::Class';
1813 my $meta = $metaclass->initialize($class);
1815 $meta->add_method(meta => sub{
1816 return $metaclass->initialize(ref($_[0]) || $_[0]);
1819 $meta->superclasses($base_class)
1820 unless $meta->superclasses;
1822 # make a class type for each Mouse class
1823 Mouse::Util::TypeConstraints::class_type($class)
1824 unless Mouse::Util::TypeConstraints::find_type_constraint($class);
1830 BEGIN{ # lib/Mouse/Meta/Attribute.pm
1831 package Mouse::Meta::Attribute;
1832 use Mouse::Util qw(:meta); # enables strict and warnings
1836 use Mouse::Meta::TypeConstraint;
1838 #use Mouse::Meta::Method::Accessor;
1839 use Mouse::Meta::Method::Delegation;
1841 sub _process_options{
1842 my($class, $name, $args) = @_;
1844 # XXX: for backward compatibility (with method modifiers)
1845 if($class->can('canonicalize_args') != \&canonicalize_args){
1846 %{$args} = $class->canonicalize_args($name, %{$args});
1849 # taken from Class::MOP::Attribute::new
1852 or $class->throw_error('You must provide a name for the attribute');
1854 if(!exists $args->{init_arg}){
1855 $args->{init_arg} = $name;
1858 # 'required' requires eigher 'init_arg', 'builder', or 'default'
1859 my $can_be_required = defined( $args->{init_arg} );
1861 if(exists $args->{builder}){
1863 # Moose refuses a CODE ref builder, but Mouse doesn't for backward compatibility
1864 # This feature will be changed in a future. (gfx)
1865 $class->throw_error('builder must be a defined scalar value which is a method name')
1866 #if ref $args->{builder} || !defined $args->{builder};
1867 if !defined $args->{builder};
1871 elsif(exists $args->{default}){
1872 if(ref $args->{default} && ref($args->{default}) ne 'CODE'){
1873 $class->throw_error("References are not allowed as default values, you must "
1874 . "wrap the default of '$name' in a CODE reference (ex: sub { [] } and not [])");
1879 if( $args->{required} && !$can_be_required ) {
1880 $class->throw_error("You cannot have a required attribute ($name) without a default, builder, or an init_arg");
1883 # taken from Mouse::Meta::Attribute->new and _process_args->
1885 if(exists $args->{is}){
1886 my $is = $args->{is};
1889 $args->{reader} ||= $name;
1892 if(exists $args->{writer}){
1893 $args->{reader} ||= $name;
1896 $args->{accessor} ||= $name;
1899 elsif($is eq 'bare'){
1900 # do nothing, but don't complain (later) about missing methods
1903 $is = 'undef' if !defined $is;
1904 $class->throw_error("I do not understand this option (is => $is) on attribute ($name)");
1909 if(exists $args->{isa}){
1910 $args->{type_constraint} = Mouse::Util::TypeConstraints::find_or_create_isa_type_constraint($args->{isa});
1912 elsif(exists $args->{does}){
1913 $args->{type_constraint} = Mouse::Util::TypeConstraints::find_or_create_does_type_constraint($args->{does});
1915 $tc = $args->{type_constraint};
1917 if($args->{coerce}){
1919 || $class->throw_error("You cannot have coercion without specifying a type constraint on attribute ($name)");
1922 && $class->throw_error("You cannot have a weak reference to a coerced value on attribute ($name)");
1925 if ($args->{lazy_build}) {
1926 exists($args->{default})
1927 && $class->throw_error("You can not use lazy_build and default for the same attribute ($name)");
1930 $args->{builder} ||= "_build_${name}";
1931 if ($name =~ /^_/) {
1932 $args->{clearer} ||= "_clear${name}";
1933 $args->{predicate} ||= "_has${name}";
1936 $args->{clearer} ||= "clear_${name}";
1937 $args->{predicate} ||= "has_${name}";
1941 if ($args->{auto_deref}) {
1943 || $class->throw_error("You cannot auto-dereference without specifying a type constraint on attribute ($name)");
1945 ( $tc->is_a_type_of('ArrayRef') || $tc->is_a_type_of('HashRef') )
1946 || $class->throw_error("You cannot auto-dereference anything other than a ArrayRef or HashRef on attribute ($name)");
1949 if (exists $args->{trigger}) {
1950 ('CODE' eq ref $args->{trigger})
1951 || $class->throw_error("Trigger must be a CODE ref on attribute ($name)");
1954 if ($args->{lazy}) {
1955 (exists $args->{default} || defined $args->{builder})
1956 || $class->throw_error("You cannot have lazy attribute ($name) without specifying a default value for it");
1966 my %args = (@_ == 1) ? %{ $_[0] } : @_;
1968 $class->_process_options($name, \%args);
1970 $args{name} = $name;
1972 my $self = bless \%args, $class;
1975 if($class ne __PACKAGE__){
1976 $class->meta->_initialize_object($self, \%args);
1979 # XXX: there is no fast way to check attribute validity
1983 # Carp::cluck("Found unknown argument(s) passed to '$name' attribute constructor in '$class': @bad");
1989 sub has_read_method { $_[0]->has_reader || $_[0]->has_accessor }
1990 sub has_write_method { $_[0]->has_writer || $_[0]->has_accessor }
1992 sub _create_args { # DEPRECATED
1993 $_[0]->{_create_args} = $_[1] if @_ > 1;
1994 $_[0]->{_create_args}
1997 sub interpolate_class{
1998 my($class, $args) = @_;
2000 if(my $metaclass = delete $args->{metaclass}){
2001 $class = Mouse::Util::resolve_metaclass_alias( Attribute => $metaclass );
2005 if(my $traits_ref = delete $args->{traits}){
2007 for (my $i = 0; $i < @{$traits_ref}; $i++) {
2008 my $trait = Mouse::Util::resolve_metaclass_alias(Attribute => $traits_ref->[$i], trait => 1);
2010 next if $class->does($trait);
2012 push @traits, $trait;
2014 # are there options?
2015 push @traits, $traits_ref->[++$i]
2016 if ref($traits_ref->[$i+1]);
2020 $class = Mouse::Meta::Class->create_anon_class(
2021 superclasses => [ $class ],
2028 return( $class, @traits );
2031 sub canonicalize_args{ # DEPRECATED
2032 my ($self, $name, %args) = @_;
2034 Carp::cluck("$self->canonicalize_args has been deprecated."
2035 . "Use \$self->_process_options instead.")
2036 if Mouse::Util::_MOUSE_VERBOSE;
2041 sub create { # DEPRECATED
2042 my ($self, $class, $name, %args) = @_;
2044 Carp::cluck("$self->create has been deprecated."
2045 . "Use \$meta->add_attribute and \$attr->install_accessors instead.")
2046 if Mouse::Util::_MOUSE_VERBOSE;
2052 sub _coerce_and_verify {
2053 my($self, $value, $instance) = @_;
2055 my $type_constraint = $self->{type_constraint};
2056 return $value if !defined $type_constraint;
2058 if ($self->should_coerce && $type_constraint->has_coercion) {
2059 $value = $type_constraint->coerce($value);
2062 $self->verify_against_type_constraint($value);
2067 sub verify_against_type_constraint {
2068 my ($self, $value) = @_;
2070 my $type_constraint = $self->{type_constraint};
2071 return 1 if !$type_constraint;
2072 return 1 if $type_constraint->check($value);
2074 $self->verify_type_constraint_error($self->name, $value, $type_constraint);
2077 sub verify_type_constraint_error {
2078 my($self, $name, $value, $type) = @_;
2079 $self->throw_error("Attribute ($name) does not pass the type constraint because: "
2080 . $type->get_message($value));
2083 sub coerce_constraint { # DEPRECATED
2084 my $type = $_[0]->{type_constraint}
2087 Carp::cluck("coerce_constraint() has been deprecated, which was an internal utility anyway");
2089 return Mouse::Util::TypeConstraints->typecast_constraints($_[0]->associated_class->name, $type, $_[1]);
2092 sub clone_and_inherit_options{
2093 my($self, %args) = @_;
2095 my($attribute_class, @traits) = ref($self)->interpolate_class(\%args);
2097 $args{traits} = \@traits if @traits;
2098 # do not inherit the 'handles' attribute
2099 foreach my $name(keys %{$self}){
2100 if(!exists $args{$name} && $name ne 'handles'){
2101 $args{$name} = $self->{$name};
2104 return $attribute_class->new($self->name, %args);
2107 sub clone_parent { # DEPRECATED
2111 my %args = ($self->get_parent_args($class, $name), @_);
2113 Carp::cluck("$self->clone_parent has been deprecated."
2114 . "Use \$meta->add_attribute and \$attr->install_accessors instead.")
2115 if Mouse::Util::_MOUSE_VERBOSE;
2117 $self->clone_and_inherited_args($class, $name, %args);
2120 sub get_parent_args { # DEPRECATED
2125 for my $super ($class->linearized_isa) {
2126 my $super_attr = $super->can("meta") && $super->meta->get_attribute($name)
2128 return %{ $super_attr->_create_args };
2131 $self->throw_error("Could not find an attribute by the name of '$name' to inherit from");
2135 sub get_read_method {
2136 $_[0]->reader || $_[0]->accessor
2138 sub get_write_method {
2139 $_[0]->writer || $_[0]->accessor
2142 sub get_read_method_ref{
2145 $self->{_read_method_ref} ||= do{
2146 my $metaclass = $self->associated_class
2147 or $self->throw_error('No asocciated class for ' . $self->name);
2149 my $reader = $self->{reader} || $self->{accessor};
2151 $metaclass->name->can($reader);
2154 $self->accessor_metaclass->_generate_reader($self, $metaclass);
2159 sub get_write_method_ref{
2162 $self->{_write_method_ref} ||= do{
2163 my $metaclass = $self->associated_class
2164 or $self->throw_error('No asocciated class for ' . $self->name);
2166 my $reader = $self->{writer} || $self->{accessor};
2168 $metaclass->name->can($reader);
2171 $self->accessor_metaclass->_generate_writer($self, $metaclass);
2176 sub _canonicalize_handles {
2177 my($self, $handles) = @_;
2179 if (ref($handles) eq 'HASH') {
2182 elsif (ref($handles) eq 'ARRAY') {
2183 return map { $_ => $_ } @$handles;
2185 elsif (ref($handles) eq 'Regexp') {
2186 my $class_or_role = ($self->{isa} || $self->{does})
2187 || $self->throw_error("Cannot delegate methods based on a Regexp without a type constraint (isa)");
2189 my $meta = Mouse::Meta::Class->initialize("$class_or_role"); # "" for stringify
2190 return map { $_ => $_ }
2191 grep { !Mouse::Object->can($_) && $_ =~ $handles }
2192 Mouse::Util::is_a_metarole($meta)
2193 ? $meta->get_method_list
2194 : $meta->get_all_method_names;
2197 $self->throw_error("Unable to canonicalize the 'handles' option with $handles");
2201 sub associate_method{
2202 my ($attribute, $method_name) = @_;
2203 $attribute->{associated_methods}++;
2207 sub delegation_metaclass() { 'Mouse::Meta::Method::Delegation' }
2209 sub install_accessors{
2210 my($attribute) = @_;
2212 my $metaclass = $attribute->associated_class;
2213 my $accessor_class = $attribute->accessor_metaclass;
2215 foreach my $type(qw(accessor reader writer predicate clearer)){
2216 if(exists $attribute->{$type}){
2217 my $generator = '_generate_' . $type;
2218 my $code = $accessor_class->$generator($attribute, $metaclass);
2219 $metaclass->add_method($attribute->{$type} => $code);
2220 $attribute->associate_method($attribute->{$type});
2224 # install delegation
2225 if(exists $attribute->{handles}){
2226 my $delegation_class = $attribute->delegation_metaclass;
2227 my %handles = $attribute->_canonicalize_handles($attribute->{handles});
2228 my $reader = $attribute->get_read_method_ref;
2230 while(my($handle_name, $method_to_call) = each %handles){
2231 my $code = $delegation_class->_generate_delegation($attribute, $metaclass,
2232 $reader, $handle_name, $method_to_call);
2234 $metaclass->add_method($handle_name => $code);
2235 $attribute->associate_method($handle_name);
2239 if($attribute->can('create') != \&create){
2240 # backword compatibility
2241 $attribute->create($metaclass, $attribute->name, %{$attribute});
2250 my $metaclass = (ref $self && $self->associated_class) || 'Mouse::Meta::Class';
2251 $metaclass->throw_error(@_, depth => 1);
2255 BEGIN{ # lib/Mouse/Meta/Class.pm
2256 package Mouse::Meta::Class;
2257 use Mouse::Util qw/:meta get_linear_isa not_supported/; # enables strict and warnings
2259 use Scalar::Util qw/blessed weaken/;
2261 use Mouse::Meta::Module;
2262 our @ISA = qw(Mouse::Meta::Module);
2264 sub attribute_metaclass;
2265 sub method_metaclass;
2267 sub constructor_class;
2268 sub destructor_class;
2270 my @MetaClassTypes = qw(
2277 sub _construct_meta {
2278 my($class, %args) = @_;
2280 $args{attributes} = {};
2281 $args{methods} = {};
2284 $args{superclasses} = do {
2286 \@{ $args{package} . '::ISA' };
2289 my $self = bless \%args, ref($class) || $class;
2290 if(ref($self) ne __PACKAGE__){
2291 $self->meta->_initialize_object($self, \%args);
2296 sub create_anon_class{
2298 return $self->create(undef, @_);
2305 sub calculate_all_roles {
2308 return grep { !$seen{ $_->name }++ }
2309 map { $_->calculate_all_roles } @{ $self->roles };
2316 foreach my $super(@_){
2317 Mouse::Util::load_class($super);
2318 my $meta = Mouse::Util::get_metaclass_by_name($super);
2320 next if not defined $meta;
2322 if(Mouse::Util::is_a_metarole($meta)){
2323 $self->throw_error("You cannot inherit from a Mouse Role ($super)");
2326 next if $self->isa(ref $meta); # _superclass_meta_is_compatible
2328 $self->_reconcile_with_superclass_meta($meta);
2330 @{ $self->{superclasses} } = @_;
2333 return @{ $self->{superclasses} };
2336 sub _reconcile_with_superclass_meta {
2337 my($self, $super_meta) = @_;
2341 foreach my $metaclass_type(@MetaClassTypes){
2342 my $super_c = $super_meta->$metaclass_type();
2343 my $self_c = $self->$metaclass_type();
2345 if(!$super_c->isa($self_c)){
2346 push @incompatibles, ($metaclass_type => $super_c);
2352 foreach my $role($self->meta->calculate_all_roles){
2353 if(!$super_meta->meta->does_role($role->name)){
2354 push @roles, $role->name;
2358 #print "reconcile($self vs. $super_meta; @roles; @incompatibles)\n";
2360 require Mouse::Util::MetaRole;
2361 Mouse::Util::MetaRole::apply_metaclass_roles(
2363 metaclass => ref $super_meta,
2364 metaclass_roles => \@roles,
2370 sub find_method_by_name{
2371 my($self, $method_name) = @_;
2372 defined($method_name)
2373 or $self->throw_error('You must define a method name to find');
2375 foreach my $class( $self->linearized_isa ){
2376 my $method = $self->initialize($class)->get_method($method_name);
2377 return $method if defined $method;
2382 sub get_all_methods {
2384 return map{ $self->find_method_by_name($_) } $self->get_all_method_names;
2387 sub get_all_method_names {
2390 return grep { $uniq{$_}++ == 0 }
2391 map { Mouse::Meta::Class->initialize($_)->get_method_list() }
2392 $self->linearized_isa;
2395 sub find_attribute_by_name{
2396 my($self, $name) = @_;
2398 foreach my $class($self->linearized_isa){
2399 my $meta = Mouse::Util::get_metaclass_by_name($class) or next;
2400 $attr = $meta->get_attribute($name) and last;
2413 $attr->isa('Mouse::Meta::Attribute')
2414 || $self->throw_error("Your attribute must be an instance of Mouse::Meta::Attribute (or a subclass)");
2416 $name = $attr->name;
2419 # _process_attribute
2422 my %args = (@_ == 1) ? %{$_[0]} : @_;
2425 or $self->throw_error('You must provide a name for the attribute');
2427 if ($name =~ s/^\+//) { # inherited attributes
2428 my $inherited_attr = $self->find_attribute_by_name($name)
2429 or $self->throw_error("Could not find an attribute by the name of '$name' to inherit from in ".$self->name);
2431 $attr = $inherited_attr->clone_and_inherit_options(%args);
2434 my($attribute_class, @traits) = $self->attribute_metaclass->interpolate_class(\%args);
2435 $args{traits} = \@traits if @traits;
2437 $attr = $attribute_class->new($name, %args);
2441 weaken( $attr->{associated_class} = $self );
2443 $self->{attributes}{$attr->name} = $attr;
2444 $attr->install_accessors();
2446 if(Mouse::Util::_MOUSE_VERBOSE && !$attr->{associated_methods} && ($attr->{is} || '') ne 'bare'){
2447 Carp::cluck(qq{Attribute (}.$attr->name.qq{) of class }.$self->name.qq{ has no associated methods (did you mean to provide an "is" argument?)});
2452 sub compute_all_applicable_attributes {
2453 Carp::cluck('compute_all_applicable_attributes() has been deprecated')
2454 if Mouse::Util::_MOUSE_VERBOSE;
2455 return shift->get_all_attributes(@_)
2465 my %params = (@_ == 1) ? %{$_[0]} : @_;
2467 (blessed($object) && $object->isa($class->name))
2468 || $class->throw_error("You must pass an instance of the metaclass (" . $class->name . "), not ($object)");
2470 my $cloned = bless { %$object }, ref $object;
2471 $class->_initialize_object($cloned, \%params);
2476 sub clone_instance {
2477 my ($class, $instance, %params) = @_;
2479 Carp::cluck('clone_instance has been deprecated. Use clone_object instead')
2480 if Mouse::Util::_MOUSE_VERBOSE;
2481 return $class->clone_object($instance, %params);
2485 sub immutable_options {
2486 my ( $self, @args ) = @_;
2489 inline_constructor => 1,
2490 inline_destructor => 1,
2491 constructor_name => 'new',
2497 sub make_immutable {
2499 my %args = $self->immutable_options(@_);
2501 $self->{is_immutable}++;
2503 if ($args{inline_constructor}) {
2504 my $c = $self->constructor_class;
2505 Mouse::Util::load_class($c);
2506 $self->add_method($args{constructor_name} =>
2507 $c->_generate_constructor($self, \%args));
2510 if ($args{inline_destructor}) {
2511 my $c = $self->destructor_class;
2512 Mouse::Util::load_class($c);
2513 $self->add_method(DESTROY =>
2514 $c->_generate_destructor($self, \%args));
2517 # Moose's make_immutable returns true allowing calling code to skip setting an explicit true value
2518 # at the end of a source file.
2522 sub make_mutable { not_supported }
2524 sub is_immutable { $_[0]->{is_immutable} }
2525 sub is_mutable { !$_[0]->{is_immutable} }
2527 sub _install_modifier_pp{
2528 my( $self, $type, $name, $code ) = @_;
2529 my $into = $self->name;
2531 my $original = $into->can($name)
2532 or $self->throw_error("The method '$name' is not found in the inheritance hierarchy for class $into");
2534 my $modifier_table = $self->{modifiers}{$name};
2536 if(!$modifier_table){
2537 my(@before, @after, @around, $cache, $modified);
2542 for my $c (@before) { $c->(@_) }
2544 if(wantarray){ # list context
2545 my @rval = $cache->(@_);
2547 for my $c(@after){ $c->(@_) }
2550 elsif(defined wantarray){ # scalar context
2551 my $rval = $cache->(@_);
2553 for my $c(@after){ $c->(@_) }
2556 else{ # void context
2559 for my $c(@after){ $c->(@_) }
2564 $self->{modifiers}{$name} = $modifier_table = {
2565 original => $original,
2571 cache => \$cache, # cache for around modifiers
2574 $self->add_method($name => $modified);
2577 if($type eq 'before'){
2578 unshift @{$modifier_table->{before}}, $code;
2580 elsif($type eq 'after'){
2581 push @{$modifier_table->{after}}, $code;
2584 push @{$modifier_table->{around}}, $code;
2586 my $next = ${ $modifier_table->{cache} };
2587 ${ $modifier_table->{cache} } = sub{ $code->($next, @_) };
2593 sub _install_modifier {
2594 my ( $self, $type, $name, $code ) = @_;
2596 # load Class::Method::Modifiers first
2597 my $no_cmm_fast = do{
2599 eval q{ require Class::Method::Modifiers::Fast };
2605 $impl = \&_install_modifier_pp;
2608 my $install_modifier = Class::Method::Modifiers::Fast->can('_install_modifier');
2610 my ( $self, $type, $name, $code ) = @_;
2611 my $into = $self->name;
2612 $install_modifier->($into, $type, $name, $code);
2614 $self->add_method($name => do{
2616 \&{ $into . '::' . $name };
2622 # replace this method itself :)
2624 no warnings 'redefine';
2625 *_install_modifier = $impl;
2628 $self->$impl( $type, $name, $code );
2631 sub add_before_method_modifier {
2632 my ( $self, $name, $code ) = @_;
2633 $self->_install_modifier( 'before', $name, $code );
2636 sub add_around_method_modifier {
2637 my ( $self, $name, $code ) = @_;
2638 $self->_install_modifier( 'around', $name, $code );
2641 sub add_after_method_modifier {
2642 my ( $self, $name, $code ) = @_;
2643 $self->_install_modifier( 'after', $name, $code );
2646 sub add_override_method_modifier {
2647 my ($self, $name, $code) = @_;
2649 if($self->has_method($name)){
2650 $self->throw_error("Cannot add an override method if a local method is already present");
2653 my $package = $self->name;
2655 my $super_body = $package->can($name)
2656 or $self->throw_error("You cannot override '$name' because it has no super method");
2658 $self->add_method($name => sub {
2659 local $Mouse::SUPER_PACKAGE = $package;
2660 local $Mouse::SUPER_BODY = $super_body;
2661 local @Mouse::SUPER_ARGS = @_;
2668 sub add_augment_method_modifier {
2669 my ($self, $name, $code) = @_;
2670 if($self->has_method($name)){
2671 $self->throw_error("Cannot add an augment method if a local method is already present");
2674 my $super = $self->find_method_by_name($name)
2675 or $self->throw_error("You cannot augment '$name' because it has no super method");
2677 my $super_package = $super->package_name;
2678 my $super_body = $super->body;
2680 $self->add_method($name => sub{
2681 local $Mouse::INNER_BODY{$super_package} = $code;
2682 local $Mouse::INNER_ARGS{$super_package} = [@_];
2689 my ($self, $role_name) = @_;
2691 (defined $role_name)
2692 || $self->throw_error("You must supply a role name to look for");
2694 for my $class ($self->linearized_isa) {
2695 my $meta = Mouse::Util::get_metaclass_by_name($class)
2698 for my $role (@{ $meta->roles }) {
2700 return 1 if $role->does_role($role_name);
2708 BEGIN{ # lib/Mouse/Meta/Method.pm
2709 package Mouse::Meta::Method;
2710 use Mouse::Util qw(:meta); # enables strict and warnings
2713 '&{}' => sub{ $_[0]->body },
2720 return $class->_new(@_);
2724 my($class, %args) = @_;
2725 my $self = bless \%args, $class;
2727 if($class ne __PACKAGE__){
2728 $self->meta->_initialize_object($self, \%args);
2733 sub body { $_[0]->{body} }
2734 sub name { $_[0]->{name} }
2735 sub package_name { $_[0]->{package} }
2736 sub associated_metaclass { $_[0]->{associated_metaclass} }
2738 sub fully_qualified_name {
2740 return $self->package_name . '::' . $self->name;
2744 BEGIN{ # lib/Mouse/Meta/Method/Accessor.pm
2745 package Mouse::Meta::Method::Accessor;
2746 use Mouse::Util qw(:meta); # enables strict and warnings
2749 my(undef, $self_var, $attr_name) = @_;
2750 return sprintf '%s->{q{%s}}', $self_var, $attr_name;
2753 sub _generate_accessor_any{
2754 my($method_class, $type, $attribute, $class) = @_;
2756 my $name = $attribute->name;
2757 my $default = $attribute->default;
2758 my $constraint = $attribute->type_constraint;
2759 my $builder = $attribute->builder;
2760 my $trigger = $attribute->trigger;
2761 my $is_weak = $attribute->is_weak_ref;
2762 my $should_deref = $attribute->should_auto_deref;
2763 my $should_coerce = (defined($constraint) && $constraint->has_coercion && $attribute->should_coerce);
2765 my $compiled_type_constraint = defined($constraint) ? $constraint->_compiled_type_constraint : undef;
2768 my $slot = $method_class->_inline_slot($self, $name);;
2770 my $accessor = sprintf(qq{package %s;\n#line 1 "%s for %s (%s)"\n}, $class->name, $type, $name, __FILE__)
2773 if ($type eq 'rw' || $type eq 'wo') {
2776 'if (scalar(@_) >= 2) {' . "\n";
2780 'if(@_ < 2){ Carp::confess("Not enough arguments for the writer of '.$name.'") }'.
2784 my $value = '$_[1]';
2786 if (defined $constraint) {
2787 if ($should_coerce) {
2790 'my $val = $constraint->coerce('.$value.');';
2795 '$compiled_type_constraint->('.$value.') or
2796 $attribute->verify_type_constraint_error($name, '.$value.', $constraint);' . "\n";
2799 # if there's nothing left to do for the attribute we can return during
2801 $accessor .= 'return ' if !$is_weak && !$trigger && !$should_deref;
2803 $accessor .= "$slot = $value;\n";
2806 $accessor .= "Scalar::Util::weaken($slot) if ref $slot;\n";
2810 $accessor .= '$trigger->('.$self.', '.$value.');' . "\n";
2815 elsif($type eq 'ro') {
2816 $accessor .= 'Carp::confess("Cannot assign a value to a read-only accessor") if scalar(@_) >= 2;' . "\n";
2819 $class->throw_error("Unknown accessor type '$type'");
2822 if ($attribute->is_lazy) {
2825 if (defined $builder){
2826 $value = "$self->\$builder()";
2828 elsif (ref($default) eq 'CODE'){
2829 $value = "$self->\$default()";
2832 $value = '$default';
2835 $accessor .= "if(!exists $slot){\n";
2837 $accessor .= "$slot = \$constraint->coerce($value)";
2839 elsif(defined $constraint){
2840 $accessor .= "my \$tmp = $value;\n";
2842 $accessor .= "\$compiled_type_constraint->(\$tmp)";
2843 $accessor .= " || \$attribute->verify_type_constraint_error(\$name, \$tmp, \$constraint);\n";
2844 $accessor .= "$slot = \$tmp;\n";
2847 $accessor .= "$slot = $value;\n";
2850 $accessor .= "Scalar::Util::weaken($slot) if ref $slot;\n";
2855 if ($should_deref) {
2856 if ($constraint->is_a_type_of('ArrayRef')) {
2857 $accessor .= "return \@{ $slot || [] } if wantarray;\n";
2859 elsif($constraint->is_a_type_of('HashRef')){
2860 $accessor .= "return \%{ $slot || {} } if wantarray;\n";
2863 $class->throw_error("Can not auto de-reference the type constraint " . $constraint->name);
2867 $accessor .= "return $slot;\n}\n";
2869 #print $accessor, "\n";
2873 $code = eval $accessor;
2881 sub _generate_accessor{
2883 return $class->_generate_accessor_any(rw => @_);
2886 sub _generate_reader {
2888 return $class->_generate_accessor_any(ro => @_);
2891 sub _generate_writer {
2893 return $class->_generate_accessor_any(wo => @_);
2896 sub _generate_predicate {
2897 my (undef, $attribute, $class) = @_;
2899 my $slot = $attribute->name;
2901 return exists $_[0]->{$slot};
2905 sub _generate_clearer {
2906 my (undef, $attribute, $class) = @_;
2908 my $slot = $attribute->name;
2910 delete $_[0]->{$slot};
2915 BEGIN{ # lib/Mouse/Meta/Method/Constructor.pm
2916 package Mouse::Meta::Method::Constructor;
2917 use Mouse::Util qw(:meta); # enables strict and warnings
2920 my(undef, $self_var, $attr_name) = @_;
2921 return sprintf '%s->{q{%s}}', $self_var, $attr_name;
2924 sub _generate_constructor {
2925 my ($class, $metaclass, $args) = @_;
2927 my $associated_metaclass_name = $metaclass->name;
2929 my @attrs = $metaclass->get_all_attributes;
2931 my $buildall = $class->_generate_BUILDALL($metaclass);
2932 my $buildargs = $class->_generate_BUILDARGS($metaclass);
2933 my $processattrs = $class->_generate_processattrs($metaclass, \@attrs);
2935 my @checks = map { $_ && $_->_compiled_type_constraint }
2936 map { $_->type_constraint } @attrs;
2938 my $source = sprintf("#line %d %s\n", __LINE__, __FILE__).<<"...";
2941 return \$class->Mouse::Object::new(\@_)
2942 if \$class ne q{$associated_metaclass_name};
2945 my \$instance = bless {}, \$class;
2946 # process attributes
2957 $code = eval $source;
2964 sub _generate_processattrs {
2965 my ($method_class, $metaclass, $attrs) = @_;
2970 for my $index (0 .. @$attrs - 1) {
2973 my $attr = $attrs->[$index];
2974 my $key = $attr->name;
2976 my $init_arg = $attr->init_arg;
2977 my $type_constraint = $attr->type_constraint;
2978 my $is_weak_ref = $attr->is_weak_ref;
2981 my $instance_slot = $method_class->_inline_slot('$instance', $key);
2982 my $attr_var = "\$attrs[$index]";
2985 if(defined $type_constraint){
2986 $constraint_var = "$attr_var\->{type_constraint}";
2987 $need_coercion = ($attr->should_coerce && $type_constraint->has_coercion);
2990 $code .= "# initialize $key\n";
2992 my $post_process = '';
2993 if(defined $type_constraint){
2994 $post_process .= "\$checks[$index]->($instance_slot)";
2995 $post_process .= " or $attr_var->verify_type_constraint_error(q{$key}, $instance_slot, $constraint_var);\n";
2998 $post_process .= "Scalar::Util::weaken($instance_slot) if ref $instance_slot;\n";
3001 if (defined $init_arg) {
3002 my $value = "\$args->{q{$init_arg}}";
3004 $code .= "if (exists $value) {\n";
3007 $value = "$constraint_var->coerce($value)";
3010 $code .= "$instance_slot = $value;\n";
3011 $code .= $post_process;
3013 if ($attr->has_trigger) {
3015 $code .= "push \@triggers, [$attr_var\->{trigger}, $instance_slot];\n";
3018 $code .= "\n} else {\n";
3021 if ($attr->has_default || $attr->has_builder) {
3022 unless ($attr->is_lazy) {
3023 my $default = $attr->default;
3024 my $builder = $attr->builder;
3027 if (defined($builder)) {
3028 $value = "\$instance->$builder()";
3030 elsif (ref($default) eq 'CODE') {
3031 $value = "$attr_var\->{default}->(\$instance)";
3033 elsif (defined($default)) {
3034 $value = "$attr_var\->{default}";
3041 $value = "$constraint_var->coerce($value)";
3044 $code .= "$instance_slot = $value;\n";
3046 $code .= "Scalar::Util::weaken($instance_slot);\n";
3050 elsif ($attr->is_required) {
3051 $code .= "Carp::confess('Attribute ($key) is required');";
3054 $code .= "}\n" if defined $init_arg;
3059 if($metaclass->is_anon_class){
3060 push @res, q{$instance->{__METACLASS__} = $metaclass;};
3064 unshift @res, q{my @triggers;};
3065 push @res, q{$_->[0]->($instance, $_->[1]) for @triggers;};
3068 return join "\n", @res;
3071 sub _generate_BUILDARGS {
3072 my(undef, $metaclass) = @_;
3074 my $class = $metaclass->name;
3075 if ( $class->can('BUILDARGS') && $class->can('BUILDARGS') != \&Mouse::Object::BUILDARGS ) {
3076 return 'my $args = $class->BUILDARGS(@_)';
3081 if ( scalar @_ == 1 ) {
3082 ( ref( $_[0] ) eq 'HASH' )
3083 || Carp::confess "Single parameters to new() must be a HASH ref";
3084 $args = +{ %{ $_[0] } };
3092 sub _generate_BUILDALL {
3093 my (undef, $metaclass) = @_;
3095 return '' unless $metaclass->name->can('BUILD');
3098 for my $class ($metaclass->linearized_isa) {
3099 if (Mouse::Util::get_code_ref($class, 'BUILD')) {
3100 unshift @code, qq{${class}::BUILD(\$instance, \$args);};
3103 return join "\n", @code;
3107 BEGIN{ # lib/Mouse/Meta/Method/Delegation.pm
3108 package Mouse::Meta::Method::Delegation;
3109 use Mouse::Util qw(:meta); # enables strict and warnings
3112 sub _generate_delegation{
3113 my (undef, $attribute, $metaclass, $reader, $handle_name, $method_to_call) = @_;
3116 my $instance = shift;
3117 my $proxy = $instance->$reader();
3119 my $error = !defined($proxy) ? ' is not defined'
3120 : ref($proxy) && !Scalar::Util::blessed($proxy) ? qq{ is not an object (got '$proxy')}
3123 $instance->meta->throw_error(
3124 "Cannot delegate $handle_name to $method_to_call because "
3130 $proxy->$method_to_call(@_);
3136 BEGIN{ # lib/Mouse/Meta/Method/Destructor.pm
3137 package Mouse::Meta::Method::Destructor;
3138 use Mouse::Util qw(:meta); # enables strict and warnings
3140 sub _empty_DESTROY{ }
3142 sub _generate_destructor{
3143 my (undef, $metaclass) = @_;
3145 if(!$metaclass->name->can('DEMOLISH')){
3146 return \&_empty_DESTROY;
3149 my $demolishall = '';
3150 for my $class ($metaclass->linearized_isa) {
3151 if (Mouse::Util::get_code_ref($class, 'DEMOLISH')) {
3152 $demolishall .= "${class}::DEMOLISH(\$self);\n";
3156 my $source = sprintf("#line %d %s\n", __LINE__, __FILE__) . <<"...";
3169 die \$e if \$e; # rethrow
3176 $code = eval $source;
3184 BEGIN{ # lib/Mouse/Meta/Module.pm
3185 package Mouse::Meta::Module;
3186 use Mouse::Util qw/:meta get_code_package get_code_ref load_class not_supported/; # enables strict and warnings
3189 use Scalar::Util ();
3193 # XXX: work around a warning "useless use of a constant in void context" in 5.6.2
3194 if(&Mouse::Util::MOUSE_XS){
3195 # register meta storage for performance
3196 Mouse::Util::__register_metaclass_storage(\%METAS, 0);
3198 # ensure thread safety
3199 *CLONE = sub { Mouse::Util::__register_metaclass_storage(\%METAS, 1) };
3202 sub _metaclass_cache { # DEPRECATED
3203 my($class, $name) = @_;
3204 return $METAS{$name};
3208 my($class, $package_name, @args) = @_;
3210 ($package_name && !ref($package_name))
3211 || $class->throw_error("You must pass a package name and it cannot be blessed");
3213 return $METAS{$package_name}
3214 ||= $class->_construct_meta(package => $package_name, @args);
3218 my($class, $package_name, @args) = @_;
3220 $package_name = $package_name->name if ref $package_name;
3222 ($package_name && !ref($package_name))
3223 || $class->throw_error("You must pass a package name and it cannot be blessed");
3225 delete $METAS{$package_name};
3226 return $class->initialize($package_name, @args);
3230 my($class_or_instance) = @_;
3231 return undef unless defined $class_or_instance;
3232 return $METAS{ ref($class_or_instance) || $class_or_instance };
3235 # Means of accessing all the metaclasses that have
3236 # been initialized thus far
3237 #sub _get_all_metaclasses { %METAS }
3238 sub _get_all_metaclass_instances { values %METAS }
3239 sub _get_all_metaclass_names { keys %METAS }
3240 sub _get_metaclass_by_name { $METAS{$_[0]} }
3241 #sub _store_metaclass_by_name { $METAS{$_[0]} = $_[1] }
3242 #sub _weaken_metaclass { weaken($METAS{$_[0]}) }
3243 #sub _does_metaclass_exist { defined $METAS{$_[0]} }
3244 #sub _remove_metaclass_by_name { delete $METAS{$_[0]} }
3250 # The followings are Class::MOP specific methods
3252 #sub version { no strict 'refs'; ${shift->name.'::VERSION'} }
3253 #sub authority { no strict 'refs'; ${shift->name.'::AUTHORITY'} }
3256 # return join '-' => (
3258 # ($self->version || ()),
3259 # ($self->authority || ()),
3263 # add_attribute is an abstract method
3265 sub get_attribute_map { # DEPRECATED
3266 Carp::cluck('get_attribute_map() has been deprecated');
3267 return $_[0]->{attributes};
3270 sub has_attribute { exists $_[0]->{attributes}->{$_[1]} }
3271 sub get_attribute { $_[0]->{attributes}->{$_[1]} }
3272 sub remove_attribute { delete $_[0]->{attributes}->{$_[1]} }
3274 sub get_attribute_list{ keys %{$_[0]->{attributes}} }
3276 # XXX: for backward compatibility
3277 my %foreign = map{ $_ => undef } qw(
3278 Mouse Mouse::Role Mouse::Util Mouse::Util::TypeConstraints
3279 Carp Scalar::Util List::Util
3282 # my($self, $code) = @_;
3284 return !exists $foreign{ get_code_package($_[1]) };
3290 my($self, $method_name) = @_;
3292 defined($method_name)
3293 or $self->throw_error('You must define a method name');
3295 return defined($self->{methods}{$method_name}) || do{
3296 my $code = get_code_ref($self->{package}, $method_name);
3297 $code && $self->_code_is_mine($code);
3301 sub get_method_body {
3302 my($self, $method_name) = @_;
3304 defined($method_name)
3305 or $self->throw_error('You must define a method name');
3307 return $self->{methods}{$method_name} ||= do{
3308 my $code = get_code_ref($self->{package}, $method_name);
3309 $code && $self->_code_is_mine($code) ? $code : undef;
3314 my($self, $method_name) = @_;
3316 if(my $code = $self->get_method_body($method_name)){
3317 my $method_metaclass = $self->method_metaclass;
3318 load_class($method_metaclass);
3320 return $method_metaclass->wrap(
3322 name => $method_name,
3323 package => $self->name,
3324 associated_metaclass => $self,
3331 sub get_method_list {
3334 return grep { $self->has_method($_) } keys %{ $self->namespace };
3338 my $ANON_SERIAL = 0;
3343 my($self, $package_name, %options) = @_;
3345 my $class = ref($self) || $self;
3346 $self->throw_error('You must pass a package name') if @_ < 2;
3349 if(exists $options{superclasses}){
3350 if(Mouse::Util::is_a_metarole($self)){
3351 delete $options{superclasses};
3354 $superclasses = delete $options{superclasses};
3355 (ref $superclasses eq 'ARRAY')
3356 || $self->throw_error("You must pass an ARRAY ref of superclasses");
3360 my $attributes = delete $options{attributes};
3361 if(defined $attributes){
3362 (ref $attributes eq 'ARRAY' || ref $attributes eq 'HASH')
3363 || $self->throw_error("You must pass an ARRAY ref of attributes");
3365 my $methods = delete $options{methods};
3366 if(defined $methods){
3367 (ref $methods eq 'HASH')
3368 || $self->throw_error("You must pass a HASH ref of methods");
3370 my $roles = delete $options{roles};
3372 (ref $roles eq 'ARRAY')
3373 || $self->throw_error("You must pass an ARRAY ref of roles");
3378 if(!defined $package_name){ # anonymous
3379 $mortal = !$options{cache};
3381 # anonymous but immortal
3383 # something like Super::Class|Super::Class::2=Role|Role::1
3384 $cache_key = join '=' => (
3385 join('|', @{$superclasses || []}),
3386 join('|', sort @{$roles || []}),
3388 return $IMMORTALS{$cache_key} if exists $IMMORTALS{$cache_key};
3390 $options{anon_serial_id} = ++$ANON_SERIAL;
3391 $package_name = $class . '::__ANON__::' . $ANON_SERIAL;
3394 # instantiate a module
3397 ${ $package_name . '::VERSION' } = delete $options{version} if exists $options{version};
3398 ${ $package_name . '::AUTHORITY' } = delete $options{authority} if exists $options{authority};
3401 my $meta = $self->initialize( $package_name, %options);
3403 Scalar::Util::weaken $METAS{$package_name}
3406 $meta->add_method(meta => sub{
3407 $self->initialize(ref($_[0]) || $_[0]);
3410 $meta->superclasses(@{$superclasses})
3411 if defined $superclasses;
3414 # process attributes first, so that they can
3415 # install accessors, but locally defined methods
3416 # can then overwrite them. It is maybe a little odd, but
3417 # I think this should be the order of things.
3418 if (defined $attributes) {
3419 if(ref($attributes) eq 'ARRAY'){
3420 # array of Mouse::Meta::Attribute
3421 foreach my $attr (@{$attributes}) {
3422 $meta->add_attribute($attr);
3426 # hash map of name and attribute spec pairs
3427 while(my($name, $attr) = each %{$attributes}){
3428 $meta->add_attribute($name => $attr);
3432 if (defined $methods) {
3433 while(my($method_name, $method_body) = each %{$methods}){
3434 $meta->add_method($method_name, $method_body);
3437 if (defined $roles){
3438 Mouse::Util::apply_all_roles($package_name, @{$roles});
3442 $IMMORTALS{$cache_key} = $meta;
3451 return if $Mouse::Util::in_global_destruction;
3453 my $serial_id = $self->{anon_serial_id};
3455 return if !$serial_id;
3457 # @ISA is a magical variable, so we clear it manually.
3458 @{$self->{superclasses}} = () if exists $self->{superclasses};
3460 # Then, clear the symbol table hash
3461 %{$self->namespace} = ();
3463 my $name = $self->name;
3464 delete $METAS{$name};
3466 $name =~ s/ $serial_id \z//xms;
3469 delete ${$name}{ $serial_id . '::' };
3476 my($class, $message, %args) = @_;
3478 local $Carp::CarpLevel = $Carp::CarpLevel + 1 + ($args{depth} || 0);
3479 local $Carp::MaxArgNums = 20; # default is 8, usually we use named args which gets messier though
3481 if(exists $args{longmess} && !$args{longmess}){ # intentionaly longmess => 0
3482 Carp::croak($message);
3485 Carp::confess($message);
3490 BEGIN{ # lib/Mouse/Meta/Role.pm
3491 package Mouse::Meta::Role;
3492 use Mouse::Util qw(:meta not_supported english_list); # enables strict and warnings
3494 use Mouse::Meta::Module;
3495 our @ISA = qw(Mouse::Meta::Module);
3497 sub method_metaclass;
3499 sub _construct_meta {
3504 $args{methods} = {};
3505 $args{attributes} = {};
3506 $args{required_methods} = [];
3509 my $self = bless \%args, ref($class) || $class;
3510 if($class ne __PACKAGE__){
3511 $self->meta->_initialize_object($self, \%args);
3517 sub create_anon_role{
3519 return $self->create(undef, @_);
3526 sub calculate_all_roles {
3529 return grep { !$seen{ $_->name }++ }
3530 ($self, map { $_->calculate_all_roles } @{ $self->get_roles });
3533 sub get_required_method_list{
3534 return @{ $_[0]->{required_methods} };
3537 sub add_required_methods {
3538 my($self, @methods) = @_;
3539 my %required = map{ $_ => 1 } @{$self->{required_methods}};
3540 push @{$self->{required_methods}}, grep{ !$required{$_}++ && !$self->has_method($_) } @methods;
3544 sub requires_method {
3545 my($self, $name) = @_;
3546 return scalar( grep{ $_ eq $name } @{ $self->{required_methods} } ) != 0;
3553 $self->{attributes}->{$name} = (@_ == 1) ? $_[0] : { @_ };
3557 sub _check_required_methods{
3558 my($role, $applicant, $args) = @_;
3560 if($args->{_to} eq 'role'){
3561 $applicant->add_required_methods($role->get_required_method_list);
3563 else{ # to class or instance
3564 my $applicant_class_name = $applicant->name;
3567 foreach my $method_name(@{$role->{required_methods}}){
3568 next if exists $args->{aliased_methods}{$method_name};
3569 next if exists $role->{methods}{$method_name};
3570 next if $applicant_class_name->can($method_name);
3572 push @missing, $method_name;
3575 $role->throw_error(sprintf "'%s' requires the method%s %s to be implemented by '%s'",
3577 (@missing == 1 ? '' : 's'), # method or methods
3578 english_list(map{ sprintf q{'%s'}, $_ } @missing),
3579 $applicant_class_name);
3587 my($role, $applicant, $args) = @_;
3589 my $alias = $args->{-alias};
3590 my $excludes = $args->{-excludes};
3592 foreach my $method_name($role->get_method_list){
3593 next if $method_name eq 'meta';
3595 my $code = $role->get_method_body($method_name);
3597 if(!exists $excludes->{$method_name}){
3598 if(!$applicant->has_method($method_name)){
3599 # The third argument $role is used in Role::Composite
3600 $applicant->add_method($method_name => $code, $role);
3604 if(exists $alias->{$method_name}){
3605 my $dstname = $alias->{$method_name};
3607 my $dstcode = $applicant->get_method_body($dstname);
3609 if(defined($dstcode) && $dstcode != $code){
3610 $role->throw_error("Cannot create a method alias if a local method of the same name exists");
3613 $applicant->add_method($dstname => $code, $role);
3621 sub _apply_attributes{
3622 my($role, $applicant, $args) = @_;
3624 for my $attr_name ($role->get_attribute_list) {
3625 next if $applicant->has_attribute($attr_name);
3627 $applicant->add_attribute($attr_name => $role->get_attribute($attr_name));
3632 sub _apply_modifiers{
3633 my($role, $applicant, $args) = @_;
3635 if(my $modifiers = $role->{override_method_modifiers}){
3636 foreach my $method_name (keys %{$modifiers}){
3637 $applicant->add_override_method_modifier($method_name => $modifiers->{$method_name});
3641 for my $modifier_type (qw/before around after/) {
3642 my $modifiers = $role->{"${modifier_type}_method_modifiers"}
3645 my $add_modifier = "add_${modifier_type}_method_modifier";
3647 foreach my $method_name (keys %{$modifiers}){
3648 foreach my $code(@{ $modifiers->{$method_name} }){
3649 next if $applicant->{"_applied_$modifier_type"}{$method_name, $code}++; # skip applied modifiers
3650 $applicant->$add_modifier($method_name => $code);
3658 my($role, $applicant, $args) = @_;
3660 my $roles = ($args->{_to} eq 'role') ? $applicant->get_roles : $applicant->roles;
3662 foreach my $r($role, @{$role->get_roles}){
3663 if(!$applicant->does_role($r->name)){
3670 # Moose uses Application::ToInstance, Application::ToClass, Application::ToRole
3673 my $applicant = shift;
3675 my %args = (@_ == 1) ? %{ $_[0] } : @_;
3679 if(Mouse::Util::is_a_metaclass($applicant)){ # Application::ToClass
3680 $args{_to} = 'class';
3682 elsif(Mouse::Util::is_a_metarole($applicant)){ # Application::ToRole
3683 $args{_to} = 'role';
3685 else{ # Appplication::ToInstance
3686 $args{_to} = 'instance';
3687 $instance = $applicant;
3689 $applicant = (Mouse::Util::class_of($instance) || 'Mouse::Meta::Class')->create_anon_class(
3690 superclasses => [ref $instance],
3695 if($args{alias} && !exists $args{-alias}){
3696 $args{-alias} = $args{alias};
3698 if($args{excludes} && !exists $args{-excludes}){
3699 $args{-excludes} = $args{excludes};
3702 $args{aliased_methods} = {};
3703 if(my $alias = $args{-alias}){
3704 @{$args{aliased_methods}}{ values %{$alias} } = ();
3707 if(my $excludes = $args{-excludes}){
3708 $args{-excludes} = {}; # replace with a hash ref
3710 %{$args{-excludes}} = (map{ $_ => undef } @{$excludes});
3713 $args{-excludes}{$excludes} = undef;
3717 $self->_check_required_methods($applicant, \%args);
3718 $self->_apply_attributes($applicant, \%args);
3719 $self->_apply_methods($applicant, \%args);
3720 $self->_apply_modifiers($applicant, \%args);
3721 $self->_append_roles($applicant, \%args);
3724 if(defined $instance){ # Application::ToInstance
3726 bless $instance, $applicant->name;
3727 $applicant->_initialize_object($instance, $instance);
3735 my($role_class, @role_specs) = @_;
3737 require 'Mouse/Meta/Role/Composite.pm'; # we don't want to create its namespace
3739 my $composite = Mouse::Meta::Role::Composite->create_anon_role();
3741 foreach my $role_spec (@role_specs) {
3742 my($role_name, $args) = @{$role_spec};
3743 $role_name->meta->apply($composite, %{$args});
3748 sub add_before_method_modifier {
3749 my ($self, $method_name, $method) = @_;
3751 push @{ $self->{before_method_modifiers}{$method_name} ||= [] }, $method;
3754 sub add_around_method_modifier {
3755 my ($self, $method_name, $method) = @_;
3757 push @{ $self->{around_method_modifiers}{$method_name} ||= [] }, $method;
3760 sub add_after_method_modifier {
3761 my ($self, $method_name, $method) = @_;
3763 push @{ $self->{after_method_modifiers}{$method_name} ||= [] }, $method;
3767 sub get_before_method_modifiers {
3768 my ($self, $method_name) = @_;
3769 return @{ $self->{before_method_modifiers}{$method_name} ||= [] }
3771 sub get_around_method_modifiers {
3772 my ($self, $method_name) = @_;
3773 return @{ $self->{around_method_modifiers}{$method_name} ||= [] }
3775 sub get_after_method_modifiers {
3776 my ($self, $method_name) = @_;
3777 return @{ $self->{after_method_modifiers}{$method_name} ||= [] }
3780 sub add_override_method_modifier{
3781 my($self, $method_name, $method) = @_;
3783 if($self->has_method($method_name)){
3784 # This error happens in the override keyword or during role composition,
3785 # so I added a message, "A local method of ...", only for compatibility (gfx)
3786 $self->throw_error("Cannot add an override of method '$method_name' "
3787 . "because there is a local version of '$method_name'"
3788 . "(A local method of the same name as been found)");
3791 $self->{override_method_modifiers}->{$method_name} = $method;
3794 sub get_override_method_modifier {
3795 my ($self, $method_name) = @_;
3796 return $self->{override_method_modifiers}->{$method_name};
3800 my ($self, $role_name) = @_;
3802 (defined $role_name)
3803 || $self->throw_error("You must supply a role name to look for");
3805 # if we are it,.. then return true
3806 return 1 if $role_name eq $self->name;
3807 # otherwise.. check our children
3808 for my $role (@{ $self->get_roles }) {
3809 return 1 if $role->does_role($role_name);
3815 BEGIN{ # lib/Mouse/Meta/Role/Composite.pm
3816 package Mouse::Meta::Role::Composite;
3817 use Mouse::Util qw(english_list); # enables strict and warnings
3818 use Mouse::Meta::Role;
3819 our @ISA = qw(Mouse::Meta::Role);
3821 sub get_method_list{
3823 return keys %{ $self->{methods} };
3827 my($self, $method_name, $code, $role) = @_;
3829 if( ($self->{methods}{$method_name} || 0) == $code){
3830 # This role already has the same method.
3834 if($method_name ne 'meta'){
3835 my $roles = $self->{composed_roles_by_method}{$method_name} ||= [];
3836 push @{$roles}, $role;
3838 $self->{conflicting_methods}{$method_name}++;
3842 $self->{methods}{$method_name} = $code;
3843 # no need to add a subroutine to the stash
3847 sub get_method_body {
3848 my($self, $method_name) = @_;
3849 return $self->{methods}{$method_name};
3853 # my($self, $method_name) = @_;
3854 return 0; # to fool _apply_methods() in combine()
3858 # my($self, $method_name) = @_;
3859 return 0; # to fool _appply_attributes() in combine()
3862 sub has_override_method_modifier{
3863 # my($self, $method_name) = @_;
3864 return 0; # to fool _apply_modifiers() in combine()
3868 my($self, $attr_name, $spec) = @_;
3870 my $existing = $self->{attributes}{$attr_name};
3871 if($existing && $existing != $spec){
3872 $self->throw_error("We have encountered an attribute conflict with '$attr_name' "
3873 . "during composition. This is fatal error and cannot be disambiguated.");
3875 $self->SUPER::add_attribute($attr_name, $spec);
3879 sub add_override_method_modifier{
3880 my($self, $method_name, $code) = @_;
3882 my $existing = $self->{override_method_modifiers}{$method_name};
3883 if($existing && $existing != $code){
3884 $self->throw_error( "We have encountered an 'override' method conflict with '$method_name' during "
3885 . "composition (Two 'override' methods of the same name encountered). "
3886 . "This is fatal error.")
3888 $self->SUPER::add_override_method_modifier($method_name, $code);
3892 # components of apply()
3895 my($self, $applicant, $args) = @_;
3897 if(exists $self->{conflicting_methods}){
3898 my $applicant_class_name = $applicant->name;
3900 my @conflicting = sort grep{ !$applicant_class_name->can($_) } keys %{ $self->{conflicting_methods} };
3902 if(@conflicting == 1){
3903 my $method_name = $conflicting[0];
3904 my @roles = sort @{ $self->{composed_roles_by_method}{$method_name} };
3906 sprintf q{Due to a method name conflict in roles %s, the method '%s' must be implemented or excluded by '%s'},
3907 english_list(map{ sprintf q{'%s'}, $_->name } @roles), $method_name, $applicant->name
3910 elsif(@conflicting > 1){
3911 my $methods = english_list(map{ sprintf q{'%s'}, $_ } @conflicting);
3914 my $roles = english_list(
3915 sort map{ my $name = $_->name; $seen{$name}++ ? () : sprintf q{'%s'}, $name }
3916 map{ @{$_} } @{ $self->{composed_roles_by_method} }{@conflicting}
3920 sprintf q{Due to method name conflicts in roles %s, the methods %s must be implemented or excluded by '%s'},
3921 $roles, $methods, $applicant->name
3926 $self->SUPER::_apply_methods($applicant, $args);
3930 BEGIN{ # lib/Mouse/Meta/Role/Method.pm
3931 package Mouse::Meta::Role::Method;
3932 use Mouse::Util; # enables strict and warnings
3934 use Mouse::Meta::Method;
3935 our @ISA = qw(Mouse::Meta::Method);
3938 my($class, %args) = @_;
3939 my $self = bless \%args, $class;
3941 if($class ne __PACKAGE__){
3942 $self->meta->_initialize_object($self, \%args);
3948 BEGIN{ # lib/Mouse/Object.pm
3949 package Mouse::Object;
3950 use Mouse::Util qw(does dump meta); # enables strict and warnings
3958 return unless $self->can('BUILD');
3960 for my $class (reverse $self->meta->linearized_isa) {
3961 my $build = Mouse::Util::get_code_ref($class, 'BUILD')
3973 return unless $self->can('DEMOLISH');
3975 # We cannot count on being able to retrieve a previously made
3976 # metaclass, _or_ being able to make a new one during global
3977 # destruction. However, we should still be able to use mro at
3978 # that time (at least tests suggest so ;)
3980 foreach my $class (@{ Mouse::Util::get_linear_isa(ref $self) }) {
3981 my $demolish = Mouse::Util::get_code_ref($class, 'DEMOLISH')
3990 BEGIN{ # lib/Mouse/Role.pm
3991 package Mouse::Role;
3992 use Mouse::Exporter; # enables strict and warnings
3994 our $VERSION = '0.43';
3996 use Carp qw(confess);
3997 use Scalar::Util qw(blessed);
3999 use Mouse::Util qw(not_supported);
4000 use Mouse::Meta::Role;
4003 Mouse::Exporter->setup_import_methods(
4013 \&Scalar::Util::blessed,
4020 Carp::croak "Roles do not support 'extends'";
4024 my $meta = Mouse::Meta::Role->initialize(scalar caller);
4025 Mouse::Util::apply_all_roles($meta->name, @_);
4030 my $meta = Mouse::Meta::Role->initialize(scalar caller);
4033 $meta->throw_error(q{Usage: has 'name' => ( key => value, ... )})
4034 if @_ % 2; # odd number of arguments
4036 if(ref $name){ # has [qw(foo bar)] => (...)
4038 $meta->add_attribute($_ => @_);
4041 else{ # has foo => (...)
4042 $meta->add_attribute($name => @_);
4048 my $meta = Mouse::Meta::Role->initialize(scalar caller);
4052 $meta->add_before_method_modifier($_ => $code);
4058 my $meta = Mouse::Meta::Role->initialize(scalar caller);
4062 $meta->add_after_method_modifier($_ => $code);
4068 my $meta = Mouse::Meta::Role->initialize(scalar caller);
4072 $meta->add_around_method_modifier($_ => $code);
4079 return if !defined $Mouse::SUPER_BODY;
4080 $Mouse::SUPER_BODY->(@Mouse::SUPER_ARGS);
4084 # my($name, $code) = @_;
4085 Mouse::Meta::Role->initialize(scalar caller)->add_override_method_modifier(@_);
4089 # We keep the same errors messages as Moose::Role emits, here.
4091 Carp::croak "Roles cannot support 'inner'";
4095 Carp::croak "Roles cannot support 'augment'";
4099 my $meta = Mouse::Meta::Role->initialize(scalar caller);
4100 $meta->throw_error("Must specify at least one method") unless @_;
4101 $meta->add_required_methods(@_);
4113 my $class = $args{for_class}
4114 or Carp::confess("Cannot call init_meta without specifying a for_class");
4116 my $metaclass = $args{metaclass} || 'Mouse::Meta::Role';
4118 my $meta = $metaclass->initialize($class);
4120 $meta->add_method(meta => sub{
4121 $metaclass->initialize(ref($_[0]) || $_[0]);
4124 # make a role type for each Mouse role
4125 Mouse::Util::TypeConstraints::role_type($class)
4126 unless Mouse::Util::TypeConstraints::find_type_constraint($class);
4132 BEGIN{ # lib/Mouse/Util/MetaRole.pm
4133 package Mouse::Util::MetaRole;
4134 use Mouse::Util; # enables strict and warnings
4136 my @MetaClassTypes = qw(
4144 # In Mouse::Exporter::do_import():
4145 # apply_metaclass_roles(for_class => $class, metaclass_roles => \@traits)
4146 sub apply_metaclass_roles {
4149 my $for = Scalar::Util::blessed($options{for_class})
4150 ? $options{for_class}
4151 : Mouse::Util::get_metaclass_by_name($options{for_class});
4153 my $new_metaclass = _make_new_class( ref $for,
4154 $options{metaclass_roles},
4155 $options{metaclass} ? [$options{metaclass}] : undef,
4160 foreach my $mc_type(@MetaClassTypes){
4161 next if !$for->can($mc_type);
4163 if(my $roles = $options{ $mc_type . '_roles' }){
4164 push @metaclass_map,
4165 ($mc_type => _make_new_class($for->$mc_type(), $roles));
4167 elsif(my $mc = $options{$mc_type}){
4168 push @metaclass_map, ($mc_type => $mc);
4172 return $new_metaclass->reinitialize( $for, @metaclass_map );
4175 sub apply_base_class_roles {
4178 my $for = $options{for_class};
4180 my $meta = Mouse::Util::class_of($for);
4182 my $new_base = _make_new_class(
4185 [ $meta->superclasses() ],
4188 $meta->superclasses($new_base)
4189 if $new_base ne $meta->name();
4193 sub _make_new_class {
4194 my($existing_class, $roles, $superclasses) = @_;
4197 return $existing_class if !$roles;
4199 my $meta = Mouse::Meta::Class->initialize($existing_class);
4201 return $existing_class
4202 if !grep { !ref($_) && !$meta->does_role($_) } @{$roles};
4205 return Mouse::Meta::Class->create_anon_class(
4206 superclasses => $superclasses ? $superclasses : [$existing_class],
4215 } # unless Mouse.pm is loaded
4216 package Mouse::Tiny;
4218 Mouse::Exporter->setup_import_methods(also => 'Mouse');