Add built local::lib
[catagits/Gitalist.git] / local-lib5 / lib / perl5 / Moose / Meta / Class.pm
1
2 package Moose::Meta::Class;
3
4 use strict;
5 use warnings;
6
7 use Class::MOP;
8
9 use Carp ();
10 use List::Util qw( first );
11 use List::MoreUtils qw( any all uniq first_index );
12 use Scalar::Util 'weaken', 'blessed';
13
14 our $VERSION   = '0.93';
15 $VERSION = eval $VERSION;
16 our $AUTHORITY = 'cpan:STEVAN';
17
18 use Moose::Meta::Method::Overridden;
19 use Moose::Meta::Method::Augmented;
20 use Moose::Error::Default;
21 use Moose::Meta::Class::Immutable::Trait;
22 use Moose::Meta::Method::Constructor;
23 use Moose::Meta::Method::Destructor;
24
25 use base 'Class::MOP::Class';
26
27 __PACKAGE__->meta->add_attribute('roles' => (
28     reader  => 'roles',
29     default => sub { [] }
30 ));
31
32 __PACKAGE__->meta->add_attribute('role_applications' => (
33     reader  => '_get_role_applications',
34     default => sub { [] }
35 ));
36
37 __PACKAGE__->meta->add_attribute(
38     Class::MOP::Attribute->new('immutable_trait' => (
39         accessor => "immutable_trait",
40         default  => 'Moose::Meta::Class::Immutable::Trait',
41     ))
42 );
43
44 __PACKAGE__->meta->add_attribute('constructor_class' => (
45     accessor => 'constructor_class',
46     default  => 'Moose::Meta::Method::Constructor',
47 ));
48
49 __PACKAGE__->meta->add_attribute('destructor_class' => (
50     accessor => 'destructor_class',
51     default  => 'Moose::Meta::Method::Destructor',
52 ));
53
54 __PACKAGE__->meta->add_attribute('error_class' => (
55     accessor => 'error_class',
56     default  => 'Moose::Error::Default',
57 ));
58
59 sub initialize {
60     my $class = shift;
61     my $pkg   = shift;
62     return Class::MOP::get_metaclass_by_name($pkg)
63         || $class->SUPER::initialize($pkg,
64                 'attribute_metaclass' => 'Moose::Meta::Attribute',
65                 'method_metaclass'    => 'Moose::Meta::Method',
66                 'instance_metaclass'  => 'Moose::Meta::Instance',
67                 @_
68             );
69 }
70
71 sub _immutable_options {
72     my ( $self, @args ) = @_;
73
74     $self->SUPER::_immutable_options(
75         inline_destructor => 1,
76
77         # Moose always does this when an attribute is created
78         inline_accessors => 0,
79
80         @args,
81     );
82 }
83
84 sub create {
85     my ($self, $package_name, %options) = @_;
86
87     (ref $options{roles} eq 'ARRAY')
88         || $self->throw_error("You must pass an ARRAY ref of roles", data => $options{roles})
89             if exists $options{roles};
90     my $roles = delete $options{roles};
91
92     my $class = $self->SUPER::create($package_name, %options);
93
94     if ($roles) {
95         Moose::Util::apply_all_roles( $class, @$roles );
96     }
97
98     return $class;
99 }
100
101 sub _check_metaclass_compatibility {
102     my $self = shift;
103
104     if ( my @supers = $self->superclasses ) {
105         $self->_fix_metaclass_incompatibility(@supers);
106     }
107
108     $self->SUPER::_check_metaclass_compatibility(@_);
109 }
110
111 my %ANON_CLASSES;
112
113 sub create_anon_class {
114     my ($self, %options) = @_;
115
116     my $cache_ok = delete $options{cache};
117
118     # something like Super::Class|Super::Class::2=Role|Role::1
119     my $cache_key = join '=' => (
120         join('|', @{$options{superclasses} || []}),
121         join('|', sort @{$options{roles}   || []}),
122     );
123
124     if ($cache_ok && defined $ANON_CLASSES{$cache_key}) {
125         return $ANON_CLASSES{$cache_key};
126     }
127
128     my $new_class = $self->SUPER::create_anon_class(%options);
129
130     $ANON_CLASSES{$cache_key} = $new_class
131         if $cache_ok;
132
133     return $new_class;
134 }
135
136 sub add_role {
137     my ($self, $role) = @_;
138     (blessed($role) && $role->isa('Moose::Meta::Role'))
139         || $self->throw_error("Roles must be instances of Moose::Meta::Role", data => $role);
140     push @{$self->roles} => $role;
141 }
142
143 sub role_applications {
144     my ($self) = @_;
145
146     return @{$self->_get_role_applications};
147 }
148
149 sub add_role_application {
150     my ($self, $application) = @_;
151     (blessed($application) && $application->isa('Moose::Meta::Role::Application::ToClass'))
152         || $self->throw_error("Role applications must be instances of Moose::Meta::Role::Application::ToClass", data => $application);
153     push @{$self->_get_role_applications} => $application;
154 }
155
156 sub calculate_all_roles {
157     my $self = shift;
158     my %seen;
159     grep { !$seen{$_->name}++ } map { $_->calculate_all_roles } @{ $self->roles };
160 }
161
162 sub does_role {
163     my ($self, $role_name) = @_;
164
165     (defined $role_name)
166         || $self->throw_error("You must supply a role name to look for");
167
168     foreach my $class ($self->class_precedence_list) {
169         my $meta = Class::MOP::class_of($class);
170         # when a Moose metaclass is itself extended with a role,
171         # this check needs to be done since some items in the
172         # class_precedence_list might in fact be Class::MOP
173         # based still.
174         next unless $meta && $meta->can('roles');
175         foreach my $role (@{$meta->roles}) {
176             return 1 if $role->does_role($role_name);
177         }
178     }
179     return 0;
180 }
181
182 sub excludes_role {
183     my ($self, $role_name) = @_;
184
185     (defined $role_name)
186         || $self->throw_error("You must supply a role name to look for");
187
188     foreach my $class ($self->class_precedence_list) {
189         my $meta = Class::MOP::class_of($class);
190         # when a Moose metaclass is itself extended with a role,
191         # this check needs to be done since some items in the
192         # class_precedence_list might in fact be Class::MOP
193         # based still.
194         next unless $meta && $meta->can('roles');
195         foreach my $role (@{$meta->roles}) {
196             return 1 if $role->excludes_role($role_name);
197         }
198     }
199     return 0;
200 }
201
202 sub new_object {
203     my $class  = shift;
204     my $params = @_ == 1 ? $_[0] : {@_};
205     my $self   = $class->SUPER::new_object($params);
206
207     foreach my $attr ( $class->get_all_attributes() ) {
208
209         next unless $attr->can('has_trigger') && $attr->has_trigger;
210
211         my $init_arg = $attr->init_arg;
212
213         next unless defined $init_arg;
214
215         next unless exists $params->{$init_arg};
216
217         $attr->trigger->(
218             $self,
219             (
220                   $attr->should_coerce
221                 ? $attr->get_read_method_ref->($self)
222                 : $params->{$init_arg}
223             ),
224         );
225     }
226
227     return $self;
228 }
229
230 sub superclasses {
231     my $self = shift;
232     my @supers = @_;
233     foreach my $super (@supers) {
234         Class::MOP::load_class($super);
235         my $meta = Class::MOP::class_of($super);
236         $self->throw_error("You cannot inherit from a Moose Role ($super)")
237             if $meta && $meta->isa('Moose::Meta::Role')
238     }
239     return $self->SUPER::superclasses(@supers);
240 }
241
242 ### ---------------------------------------------
243
244 sub add_attribute {
245     my $self = shift;
246     my $attr =
247         (blessed $_[0] && $_[0]->isa('Class::MOP::Attribute')
248             ? $_[0]
249             : $self->_process_attribute(@_));
250     $self->SUPER::add_attribute($attr);
251     # it may be a Class::MOP::Attribute, theoretically, which doesn't have
252     # 'bare' and doesn't implement this method
253     if ($attr->can('_check_associated_methods')) {
254         $attr->_check_associated_methods;
255     }
256     return $attr;
257 }
258
259 sub add_override_method_modifier {
260     my ($self, $name, $method, $_super_package) = @_;
261
262     (!$self->has_method($name))
263         || $self->throw_error("Cannot add an override method if a local method is already present");
264
265     $self->add_method($name => Moose::Meta::Method::Overridden->new(
266         method  => $method,
267         class   => $self,
268         package => $_super_package, # need this for roles
269         name    => $name,
270     ));
271 }
272
273 sub add_augment_method_modifier {
274     my ($self, $name, $method) = @_;
275     (!$self->has_method($name))
276         || $self->throw_error("Cannot add an augment method if a local method is already present");
277
278     $self->add_method($name => Moose::Meta::Method::Augmented->new(
279         method  => $method,
280         class   => $self,
281         name    => $name,
282     ));
283 }
284
285 ## Private Utility methods ...
286
287 sub _find_next_method_by_name_which_is_not_overridden {
288     my ($self, $name) = @_;
289     foreach my $method ($self->find_all_methods_by_name($name)) {
290         return $method->{code}
291             if blessed($method->{code}) && !$method->{code}->isa('Moose::Meta::Method::Overridden');
292     }
293     return undef;
294 }
295
296 sub _fix_metaclass_incompatibility {
297     my ($self, @superclasses) = @_;
298
299     $self->_fix_one_incompatible_metaclass($_)
300         for map { Moose::Meta::Class->initialize($_) } @superclasses;
301 }
302
303 sub _fix_one_incompatible_metaclass {
304     my ($self, $meta) = @_;
305
306     return if $self->_superclass_meta_is_compatible($meta);
307
308     unless ( $self->is_pristine ) {
309         $self->throw_error(
310               "Cannot attempt to reinitialize metaclass for "
311             . $self->name
312             . ", it isn't pristine" );
313     }
314
315     $self->_reconcile_with_superclass_meta($meta);
316 }
317
318 sub _superclass_meta_is_compatible {
319     my ($self, $super_meta) = @_;
320
321     next unless $super_meta->isa("Class::MOP::Class");
322
323     my $super_meta_name
324         = $super_meta->is_immutable
325         ? $super_meta->_get_mutable_metaclass_name
326         : ref($super_meta);
327
328     return 1
329         if $self->isa($super_meta_name)
330             and
331            $self->instance_metaclass->isa( $super_meta->instance_metaclass );
332 }
333
334 # I don't want to have to type this >1 time
335 my @MetaClassTypes =
336     qw( attribute_metaclass
337         method_metaclass
338         wrapped_method_metaclass
339         instance_metaclass
340         constructor_class
341         destructor_class
342         error_class );
343
344 sub _reconcile_with_superclass_meta {
345     my ($self, $super_meta) = @_;
346
347     my $super_meta_name
348         = $super_meta->is_immutable
349         ? $super_meta->_get_mutable_metaclass_name
350         : ref($super_meta);
351
352     my $self_metaclass = ref $self;
353
354     # If neither of these is true we have a more serious
355     # incompatibility that we just cannot fix (yet?).
356     if ( $super_meta_name->isa( ref $self )
357         && all { $super_meta->$_->isa( $self->$_ ) } @MetaClassTypes ) {
358         $self->_reinitialize_with($super_meta);
359     }
360     elsif ( $self->_all_metaclasses_differ_by_roles_only($super_meta) ) {
361         $self->_reconcile_role_differences($super_meta);
362     }
363 }
364
365 sub _reinitialize_with {
366     my ( $self, $new_meta ) = @_;
367
368     my $new_self = $new_meta->reinitialize(
369         $self->name,
370         attribute_metaclass => $new_meta->attribute_metaclass,
371         method_metaclass    => $new_meta->method_metaclass,
372         instance_metaclass  => $new_meta->instance_metaclass,
373     );
374
375     $new_self->$_( $new_meta->$_ )
376         for qw( constructor_class destructor_class error_class );
377
378     %$self = %$new_self;
379
380     bless $self, ref $new_self;
381
382     # We need to replace the cached metaclass instance or else when it
383     # goes out of scope Class::MOP::Class destroy's the namespace for
384     # the metaclass's class, causing much havoc.
385     Class::MOP::store_metaclass_by_name( $self->name, $self );
386     Class::MOP::weaken_metaclass( $self->name ) if $self->is_anon_class;
387 }
388
389 # In the more complex case, we share a common ancestor with our
390 # superclass's metaclass, but each metaclass (ours and the parent's)
391 # has a different set of roles applied. We reconcile this by first
392 # reinitializing into the parent class, and _then_ applying our own
393 # roles.
394 sub _all_metaclasses_differ_by_roles_only {
395     my ($self, $super_meta) = @_;
396
397     for my $pair (
398         [ ref $self, ref $super_meta ],
399         map { [ $self->$_, $super_meta->$_ ] } @MetaClassTypes
400         ) {
401
402         next if $pair->[0] eq $pair->[1];
403
404         my $self_meta_meta  = Class::MOP::Class->initialize( $pair->[0] );
405         my $super_meta_meta = Class::MOP::Class->initialize( $pair->[1] );
406
407         my $common_ancestor
408             = _find_common_ancestor( $self_meta_meta, $super_meta_meta );
409
410         return unless $common_ancestor;
411
412         return
413             unless _is_role_only_subclass_of(
414             $self_meta_meta,
415             $common_ancestor,
416             )
417             && _is_role_only_subclass_of(
418             $super_meta_meta,
419             $common_ancestor,
420             );
421     }
422
423     return 1;
424 }
425
426 # This, and some other functions, could be called as methods, but
427 # they're not for two reasons. One, we just end up ignoring the first
428 # argument, because we can't call these directly on one of the real
429 # arguments, because one of them could be a Class::MOP::Class object
430 # and not a Moose::Meta::Class. Second, only a completely insane
431 # person would attempt to subclass this stuff!
432 sub _find_common_ancestor {
433     my ($meta1, $meta2) = @_;
434
435     # FIXME? This doesn't account for multiple inheritance (not sure
436     # if it needs to though). For example, is somewhere in $meta1's
437     # history it inherits from both ClassA and ClassB, and $meta2
438     # inherits from ClassB & ClassA, does it matter? And what crazy
439     # fool would do that anyway?
440
441     my %meta1_parents = map { $_ => 1 } $meta1->linearized_isa;
442
443     return first { $meta1_parents{$_} } $meta2->linearized_isa;
444 }
445
446 sub _is_role_only_subclass_of {
447     my ($meta, $ancestor) = @_;
448
449     return 1 if $meta->name eq $ancestor;
450
451     my @roles = _all_roles_until( $meta, $ancestor );
452
453     my %role_packages = map { $_->name => 1 } @roles;
454
455     my $ancestor_meta = Class::MOP::Class->initialize($ancestor);
456
457     my %shared_ancestors = map { $_ => 1 } $ancestor_meta->linearized_isa;
458
459     for my $method ( $meta->get_all_methods() ) {
460         next if $method->name eq 'meta';
461         next if $method->can('associated_attribute');
462
463         next
464             if $role_packages{ $method->original_package_name }
465                 || $shared_ancestors{ $method->original_package_name };
466
467         return 0;
468     }
469
470     # FIXME - this really isn't right. Just because an attribute is
471     # defined in a role doesn't mean it isn't _also_ defined in the
472     # subclass.
473     for my $attr ( $meta->get_all_attributes ) {
474         next if $shared_ancestors{ $attr->associated_class->name };
475
476         next if any { $_->has_attribute( $attr->name ) } @roles;
477
478         return 0;
479     }
480
481     return 1;
482 }
483
484 sub _all_roles {
485     my $meta = shift;
486
487     return _all_roles_until($meta);
488 }
489
490 sub _all_roles_until {
491     my ($meta, $stop_at_class) = @_;
492
493     return unless $meta->can('calculate_all_roles');
494
495     my @roles = $meta->calculate_all_roles;
496
497     for my $class ( $meta->linearized_isa ) {
498         last if $stop_at_class && $stop_at_class eq $class;
499
500         my $meta = Class::MOP::Class->initialize($class);
501         last unless $meta->can('calculate_all_roles');
502
503         push @roles, $meta->calculate_all_roles;
504     }
505
506     return uniq @roles;
507 }
508
509 sub _reconcile_role_differences {
510     my ($self, $super_meta) = @_;
511
512     my $self_meta = Class::MOP::class_of($self);
513
514     my %roles;
515
516     if ( my @roles = map { $_->name } _all_roles($self_meta) ) {
517         $roles{metaclass_roles} = \@roles;
518     }
519
520     for my $thing (@MetaClassTypes) {
521         my $name = $self->$thing();
522
523         my $thing_meta = Class::MOP::Class->initialize($name);
524
525         my @roles = map { $_->name } _all_roles($thing_meta)
526             or next;
527
528         $roles{ $thing . '_roles' } = \@roles;
529     }
530
531     $self->_reinitialize_with($super_meta);
532
533     Moose::Util::MetaRole::apply_metaclass_roles(
534         for_class => $self->name,
535         %roles,
536     );
537
538     return $self;
539 }
540
541 sub _process_attribute {
542     my ( $self, $name, @args ) = @_;
543
544     @args = %{$args[0]} if scalar @args == 1 && ref($args[0]) eq 'HASH';
545
546     if (($name || '') =~ /^\+(.*)/) {
547         return $self->_process_inherited_attribute($1, @args);
548     }
549     else {
550         return $self->_process_new_attribute($name, @args);
551     }
552 }
553
554 sub _process_new_attribute {
555     my ( $self, $name, @args ) = @_;
556
557     $self->attribute_metaclass->interpolate_class_and_new($name, @args);
558 }
559
560 sub _process_inherited_attribute {
561     my ($self, $attr_name, %options) = @_;
562     my $inherited_attr = $self->find_attribute_by_name($attr_name);
563     (defined $inherited_attr)
564         || $self->throw_error("Could not find an attribute by the name of '$attr_name' to inherit from in ${\$self->name}", data => $attr_name);
565     if ($inherited_attr->isa('Moose::Meta::Attribute')) {
566         return $inherited_attr->clone_and_inherit_options(%options);
567     }
568     else {
569         # NOTE:
570         # kind of a kludge to handle Class::MOP::Attributes
571         return $inherited_attr->Moose::Meta::Attribute::clone_and_inherit_options(%options);
572     }
573 }
574
575 ## -------------------------------------------------
576
577 our $error_level;
578
579 sub throw_error {
580     my ( $self, @args ) = @_;
581     local $error_level = ($error_level || 0) + 1;
582     $self->raise_error($self->create_error(@args));
583 }
584
585 sub raise_error {
586     my ( $self, @args ) = @_;
587     die @args;
588 }
589
590 sub create_error {
591     my ( $self, @args ) = @_;
592
593     require Carp::Heavy;
594
595     local $error_level = ($error_level || 0 ) + 1;
596
597     if ( @args % 2 == 1 ) {
598         unshift @args, "message";
599     }
600
601     my %args = ( metaclass => $self, last_error => $@, @args );
602
603     $args{depth} += $error_level;
604
605     my $class = ref $self ? $self->error_class : "Moose::Error::Default";
606
607     Class::MOP::load_class($class);
608
609     $class->new(
610         Carp::caller_info($args{depth}),
611         %args
612     );
613 }
614
615 1;
616
617 __END__
618
619 =pod
620
621 =head1 NAME
622
623 Moose::Meta::Class - The Moose metaclass
624
625 =head1 DESCRIPTION
626
627 This class is a subclass of L<Class::MOP::Class> that provides
628 additional Moose-specific functionality.
629
630 To really understand this class, you will need to start with the
631 L<Class::MOP::Class> documentation. This class can be understood as a
632 set of additional features on top of the basic feature provided by
633 that parent class.
634
635 =head1 INHERITANCE
636
637 C<Moose::Meta::Class> is a subclass of L<Class::MOP::Class>.
638
639 =head1 METHODS
640
641 =over 4
642
643 =item B<< Moose::Meta::Class->initialize($package_name, %options) >>
644
645 This overrides the parent's method in order to provide its own
646 defaults for the C<attribute_metaclass>, C<instance_metaclass>, and
647 C<method_metaclass> options.
648
649 These all default to the appropriate Moose class.
650
651 =item B<< Moose::Meta::Class->create($package_name, %options) >>
652
653 This overrides the parent's method in order to accept a C<roles>
654 option. This should be an array reference containing roles
655 that the class does, each optionally followed by a hashref of options
656 (C<-excludes> and C<-alias>).
657
658   my $metaclass = Moose::Meta::Class->create( 'New::Class', roles => [...] );
659
660 =item B<< Moose::Meta::Class->create_anon_class >>
661
662 This overrides the parent's method to accept a C<roles> option, just
663 as C<create> does.
664
665 It also accepts a C<cache> option. If this is true, then the anonymous
666 class will be cached based on its superclasses and roles. If an
667 existing anonymous class in the cache has the same superclasses and
668 roles, it will be reused.
669
670   my $metaclass = Moose::Meta::Class->create_anon_class(
671       superclasses => ['Foo'],
672       roles        => [qw/Some Roles Go Here/],
673       cache        => 1,
674   );
675
676 =item B<< $metaclass->make_immutable(%options) >>
677
678 This overrides the parent's method to add a few options. Specifically,
679 it uses the Moose-specific constructor and destructor classes, and
680 enables inlining the destructor.
681
682 Also, since Moose always inlines attributes, it sets the
683 C<inline_accessors> option to false.
684
685 =item B<< $metaclass->new_object(%params) >>
686
687 This overrides the parent's method in order to add support for
688 attribute triggers.
689
690 =item B<< $metaclass->add_override_method_modifier($name, $sub) >>
691
692 This adds an C<override> method modifier to the package.
693
694 =item B<< $metaclass->add_augment_method_modifier($name, $sub) >>
695
696 This adds an C<augment> method modifier to the package.
697
698 =item B<< $metaclass->calculate_all_roles >>
699
700 This will return a unique array of C<Moose::Meta::Role> instances
701 which are attached to this class.
702
703 =item B<< $metaclass->add_role($role) >>
704
705 This takes a L<Moose::Meta::Role> object, and adds it to the class's
706 list of roles. This I<does not> actually apply the role to the class.
707
708 =item B<< $metaclass->role_applications >>
709
710 Returns a list of L<Moose::Meta::Role::Application::ToClass>
711 objects, which contain the arguments to role application.
712
713 =item B<< $metaclass->add_role_application($application) >>
714
715 This takes a L<Moose::Meta::Role::Application::ToClass> object, and
716 adds it to the class's list of role applications. This I<does not>
717 actually apply any role to the class; it is only for tracking role
718 applications.
719
720 =item B<< $metaclass->does_role($role_name) >>
721
722 This returns a boolean indicating whether or not the class does the
723 specified role. This tests both the class and its parents.
724
725 =item B<< $metaclass->excludes_role($role_name) >>
726
727 A class excludes a role if it has already composed a role which
728 excludes the named role. This tests both the class and its parents.
729
730 =item B<< $metaclass->add_attribute($attr_name, %params|$params) >>
731
732 This overrides the parent's method in order to allow the parameters to
733 be provided as a hash reference.
734
735 =item B<< $metaclass->constructor_class ($class_name) >>
736
737 =item B<< $metaclass->destructor_class ($class_name) >>
738
739 These are the names of classes used when making a class
740 immutable. These default to L<Moose::Meta::Method::Constructor> and
741 L<Moose::Meta::Method::Destructor> respectively. These accessors are
742 read-write, so you can use them to change the class name.
743
744 =item B<< $metaclass->error_class($class_name) >>
745
746 The name of the class used to throw errors. This defaults to
747 L<Moose::Error::Default>, which generates an error with a stacktrace
748 just like C<Carp::confess>.
749
750 =item B<< $metaclass->throw_error($message, %extra) >>
751
752 Throws the error created by C<create_error> using C<raise_error>
753
754 =back
755
756 =head1 BUGS
757
758 All complex software has bugs lurking in it, and this module is no
759 exception. If you find a bug please either email me, or add the bug
760 to cpan-RT.
761
762 =head1 AUTHOR
763
764 Stevan Little E<lt>stevan@iinteractive.comE<gt>
765
766 =head1 COPYRIGHT AND LICENSE
767
768 Copyright 2006-2009 by Infinity Interactive, Inc.
769
770 L<http://www.iinteractive.com>
771
772 This library is free software; you can redistribute it and/or modify
773 it under the same terms as Perl itself.
774
775 =cut
776