2 package Moose::Meta::Class;
9 use Carp qw( confess );
11 use List::Util qw( first );
12 use List::MoreUtils qw( any all uniq first_index );
13 use Scalar::Util 'blessed';
15 use Moose::Meta::Method::Overridden;
16 use Moose::Meta::Method::Augmented;
17 use Moose::Error::Default;
18 use Moose::Meta::Class::Immutable::Trait;
19 use Moose::Meta::Method::Constructor;
20 use Moose::Meta::Method::Destructor;
21 use Moose::Meta::Method::Meta;
23 use Class::MOP::MiniTrait;
25 use base 'Class::MOP::Class';
27 Class::MOP::MiniTrait::apply(__PACKAGE__, 'Moose::Meta::Object::Trait');
29 __PACKAGE__->meta->add_attribute('roles' => (
34 __PACKAGE__->meta->add_attribute('role_applications' => (
35 reader => '_get_role_applications',
39 __PACKAGE__->meta->add_attribute(
40 Class::MOP::Attribute->new('immutable_trait' => (
41 accessor => "immutable_trait",
42 default => 'Moose::Meta::Class::Immutable::Trait',
46 __PACKAGE__->meta->add_attribute('constructor_class' => (
47 accessor => 'constructor_class',
48 default => 'Moose::Meta::Method::Constructor',
51 __PACKAGE__->meta->add_attribute('destructor_class' => (
52 accessor => 'destructor_class',
53 default => 'Moose::Meta::Method::Destructor',
56 __PACKAGE__->meta->add_attribute('error_class' => (
57 accessor => 'error_class',
58 default => 'Moose::Error::Default',
64 unshift @args, 'package' if @args % 2;
66 my $package = delete $opts{package};
67 return Class::MOP::get_metaclass_by_name($package)
68 || $class->SUPER::initialize($package,
69 'attribute_metaclass' => 'Moose::Meta::Attribute',
70 'method_metaclass' => 'Moose::Meta::Method',
71 'instance_metaclass' => 'Moose::Meta::Instance',
80 unshift @args, 'package' if @args % 2 == 1;
83 (ref $options{roles} eq 'ARRAY')
84 || $class->throw_error("You must pass an ARRAY ref of roles", data => $options{roles})
85 if exists $options{roles};
87 my $package = delete $options{package};
88 my $roles = delete $options{roles};
90 my $new_meta = $class->SUPER::create($package, %options);
93 Moose::Util::apply_all_roles( $new_meta, @$roles );
99 sub _meta_method_class { 'Moose::Meta::Method::Meta' }
101 sub _anon_package_prefix { 'Moose::Meta::Class::__ANON__::SERIAL::' }
103 sub _anon_cache_key {
107 my $superclass_key = join('|',
108 map { $_->[0] } @{ Data::OptList::mkopt($options{superclasses} || []) }
111 my $roles = Data::OptList::mkopt(($options{roles} || []), {
113 val_test => sub { ref($_[0]) eq 'HASH' },
117 for my $role_spec (@$roles) {
118 my ($role, $params) = @$role_spec;
119 $params = { %$params } if $params;
121 my $key = blessed($role) ? $role->name : $role;
123 if ($params && %$params) {
124 my $alias = delete $params->{'-alias'}
125 || delete $params->{'alias'}
127 my $excludes = delete $params->{'-excludes'}
128 || delete $params->{'excludes'}
130 $excludes = [$excludes] unless ref($excludes) eq 'ARRAY';
133 # disable this warning until 2.02
134 # warn "Roles with parameters cannot be cached. Consider "
135 # . "applying the parameters before calling "
136 # . "create_anon_class, or using 'weaken => 0' instead";
140 $key .= '<' . join('+', 'a', join('%', sort %$alias),
141 'e', join('%', sort @$excludes)) . '>';
144 push @role_keys, $key;
147 my $role_key = join('|', sort @role_keys);
149 # Makes something like Super::Class|Super::Class::2=Role|Role::1
150 return join('=', $superclass_key, $role_key);
157 my $meta = blessed $pkg ? $pkg : Class::MOP::class_of($pkg);
159 my %existing_classes;
161 %existing_classes = map { $_ => $meta->$_() } qw(
164 wrapped_method_metaclass
172 return $self->SUPER::reinitialize(
180 my ($self, $role) = @_;
181 (blessed($role) && $role->isa('Moose::Meta::Role'))
182 || $self->throw_error("Roles must be instances of Moose::Meta::Role", data => $role);
183 push @{$self->roles} => $role;
186 sub role_applications {
189 return @{$self->_get_role_applications};
192 sub add_role_application {
193 my ($self, $application) = @_;
194 (blessed($application) && $application->isa('Moose::Meta::Role::Application::ToClass'))
195 || $self->throw_error("Role applications must be instances of Moose::Meta::Role::Application::ToClass", data => $application);
196 push @{$self->_get_role_applications} => $application;
199 sub calculate_all_roles {
202 grep { !$seen{$_->name}++ } map { $_->calculate_all_roles } @{ $self->roles };
205 sub calculate_all_roles_with_inheritance {
208 grep { !$seen{$_->name}++ }
209 map { Class::MOP::class_of($_)->can('calculate_all_roles')
210 ? Class::MOP::class_of($_)->calculate_all_roles
212 $self->linearized_isa;
216 my ($self, $role_name) = @_;
219 || $self->throw_error("You must supply a role name to look for");
221 foreach my $class ($self->class_precedence_list) {
222 my $meta = Class::MOP::class_of($class);
223 # when a Moose metaclass is itself extended with a role,
224 # this check needs to be done since some items in the
225 # class_precedence_list might in fact be Class::MOP
227 next unless $meta && $meta->can('roles');
228 foreach my $role (@{$meta->roles}) {
229 return 1 if $role->does_role($role_name);
236 my ($self, $role_name) = @_;
239 || $self->throw_error("You must supply a role name to look for");
241 foreach my $class ($self->class_precedence_list) {
242 my $meta = Class::MOP::class_of($class);
243 # when a Moose metaclass is itself extended with a role,
244 # this check needs to be done since some items in the
245 # class_precedence_list might in fact be Class::MOP
247 next unless $meta && $meta->can('roles');
248 foreach my $role (@{$meta->roles}) {
249 return 1 if $role->excludes_role($role_name);
257 my $params = @_ == 1 ? $_[0] : {@_};
258 my $object = $self->SUPER::new_object($params);
260 foreach my $attr ( $self->get_all_attributes() ) {
262 next unless $attr->can('has_trigger') && $attr->has_trigger;
264 my $init_arg = $attr->init_arg;
266 next unless defined $init_arg;
268 next unless exists $params->{$init_arg};
274 ? $attr->get_read_method_ref->($object)
275 : $params->{$init_arg}
280 $object->BUILDALL($params) if $object->can('BUILDALL');
285 sub _generate_fallback_constructor {
288 return $class . '->Moose::Object::new(@_)'
293 my ($params, $class) = @_;
295 'my ' . $params . ' = ',
296 $self->_inline_BUILDARGS($class, '@_'),
301 sub _inline_BUILDARGS {
303 my ($class, $args) = @_;
305 my $buildargs = $self->find_method_by_name("BUILDARGS");
308 && (!$buildargs or $buildargs->body == \&Moose::Object::BUILDARGS)) {
312 'if (scalar @_ == 1) {',
313 'if (!defined($_[0]) || ref($_[0]) ne \'HASH\') {',
314 $self->_inline_throw_error(
315 '"Single parameters to new() must be a HASH ref"',
319 '$params = { %{ $_[0] } };',
323 '"The new() method for ' . $class . ' expects a '
324 . 'hash reference or a key/value list. You passed an '
325 . 'odd number of arguments"',
327 '$params = {@_, undef};',
337 return $class . '->BUILDARGS(' . $args . ')';
341 sub _inline_slot_initializer {
343 my ($attr, $idx) = @_;
347 $self->_inline_check_required_attr($attr),
348 $self->SUPER::_inline_slot_initializer(@_),
352 sub _inline_check_required_attr {
356 return unless defined $attr->init_arg;
357 return unless $attr->can('is_required') && $attr->is_required;
358 return if $attr->has_default || $attr->has_builder;
361 'if (!exists $params->{\'' . $attr->init_arg . '\'}) {',
362 $self->_inline_throw_error(
363 '"Attribute (' . quotemeta($attr->name) . ') is required"'
369 # XXX: these two are duplicated from cmop, because we have to pass the tc stuff
370 # through to _inline_set_value - this should probably be fixed, but i'm not
371 # quite sure how. -doy
372 sub _inline_init_attr_from_constructor {
374 my ($attr, $idx) = @_;
376 my @initial_value = $attr->_inline_set_value(
378 '$params->{\'' . $attr->init_arg . '\'}',
379 '$type_constraint_bodies[' . $idx . ']',
380 '$type_constraints[' . $idx . ']',
384 push @initial_value, (
385 '$attrs->[' . $idx . ']->set_initial_value(',
387 $attr->_inline_instance_get('$instance'),
389 ) if $attr->has_initializer;
391 return @initial_value;
394 sub _inline_init_attr_from_default {
396 my ($attr, $idx) = @_;
398 return if $attr->can('is_lazy') && $attr->is_lazy;
399 my $default = $self->_inline_default_value($attr, $idx);
400 return unless $default;
402 my @initial_value = (
403 'my $default = ' . $default . ';',
404 $attr->_inline_set_value(
407 '$type_constraint_bodies[' . $idx . ']',
408 '$type_constraints[' . $idx . ']',
413 push @initial_value, (
414 '$attrs->[' . $idx . ']->set_initial_value(',
416 $attr->_inline_instance_get('$instance'),
418 ) if $attr->has_initializer;
420 return @initial_value;
423 sub _inline_extra_init {
426 $self->_inline_triggers,
427 $self->_inline_BUILDALL,
431 sub _inline_triggers {
435 my @attrs = sort { $a->name cmp $b->name } $self->get_all_attributes;
436 for my $i (0 .. $#attrs) {
437 my $attr = $attrs[$i];
439 next unless $attr->can('has_trigger') && $attr->has_trigger;
441 my $init_arg = $attr->init_arg;
442 next unless defined $init_arg;
445 'if (exists $params->{\'' . $init_arg . '\'}) {',
446 '$attrs->[' . $i . ']->trigger->(',
448 $attr->_inline_instance_get('$instance') . ',',
453 return @trigger_calls;
456 sub _inline_BUILDALL {
459 my @methods = reverse $self->find_all_methods_by_name('BUILD');
462 foreach my $method (@methods) {
464 '$instance->' . $method->{class} . '::BUILD($params);';
472 my $supers = Data::OptList::mkopt(\@_);
473 foreach my $super (@{ $supers }) {
474 my ($name, $opts) = @{ $super };
475 Class::MOP::load_class($name, $opts);
476 my $meta = Class::MOP::class_of($name);
477 $self->throw_error("You cannot inherit from a Moose Role ($name)")
478 if $meta && $meta->isa('Moose::Meta::Role')
480 return $self->SUPER::superclasses(map { $_->[0] } @{ $supers });
483 ### ---------------------------------------------
488 (blessed $_[0] && $_[0]->isa('Class::MOP::Attribute')
490 : $self->_process_attribute(@_));
491 $self->SUPER::add_attribute($attr);
492 # it may be a Class::MOP::Attribute, theoretically, which doesn't have
493 # 'bare' and doesn't implement this method
494 if ($attr->can('_check_associated_methods')) {
495 $attr->_check_associated_methods;
500 sub add_override_method_modifier {
501 my ($self, $name, $method, $_super_package) = @_;
503 (!$self->has_method($name))
504 || $self->throw_error("Cannot add an override method if a local method is already present");
506 $self->add_method($name => Moose::Meta::Method::Overridden->new(
509 package => $_super_package, # need this for roles
514 sub add_augment_method_modifier {
515 my ($self, $name, $method) = @_;
516 (!$self->has_method($name))
517 || $self->throw_error("Cannot add an augment method if a local method is already present");
519 $self->add_method($name => Moose::Meta::Method::Augmented->new(
526 ## Private Utility methods ...
528 sub _find_next_method_by_name_which_is_not_overridden {
529 my ($self, $name) = @_;
530 foreach my $method ($self->find_all_methods_by_name($name)) {
531 return $method->{code}
532 if blessed($method->{code}) && !$method->{code}->isa('Moose::Meta::Method::Overridden');
537 ## Metaclass compatibility
539 sub _base_metaclasses {
541 my %metaclasses = $self->SUPER::_base_metaclasses;
542 for my $class (keys %metaclasses) {
543 $metaclasses{$class} =~ s/^Class::MOP/Moose::Meta/;
547 error_class => 'Moose::Error::Default',
551 sub _fix_class_metaclass_incompatibility {
553 my ($super_meta) = @_;
555 $self->SUPER::_fix_class_metaclass_incompatibility(@_);
557 if ($self->_class_metaclass_can_be_made_compatible($super_meta)) {
559 || confess "Can't fix metaclass incompatibility for "
561 . " because it is not pristine.";
562 my $super_meta_name = $super_meta->_real_ref_name;
563 my $class_meta_subclass_meta_name = Moose::Util::_reconcile_roles_for_metaclass(blessed($self), $super_meta_name);
564 my $new_self = $class_meta_subclass_meta_name->reinitialize(
568 $self->_replace_self( $new_self, $class_meta_subclass_meta_name );
572 sub _fix_single_metaclass_incompatibility {
574 my ($metaclass_type, $super_meta) = @_;
576 $self->SUPER::_fix_single_metaclass_incompatibility(@_);
578 if ($self->_single_metaclass_can_be_made_compatible($super_meta, $metaclass_type)) {
580 || confess "Can't fix metaclass incompatibility for "
582 . " because it is not pristine.";
583 my $super_meta_name = $super_meta->_real_ref_name;
584 my $class_specific_meta_subclass_meta_name = Moose::Util::_reconcile_roles_for_metaclass($self->$metaclass_type, $super_meta->$metaclass_type);
585 my $new_self = $super_meta->reinitialize(
587 $metaclass_type => $class_specific_meta_subclass_meta_name,
590 $self->_replace_self( $new_self, $super_meta_name );
596 my ( $new_self, $new_class) = @_;
599 bless $self, $new_class;
601 # We need to replace the cached metaclass instance or else when it goes
602 # out of scope Class::MOP::Class destroy's the namespace for the
603 # metaclass's class, causing much havoc.
604 my $weaken = Class::MOP::metaclass_is_weak( $self->name );
605 Class::MOP::store_metaclass_by_name( $self->name, $self );
606 Class::MOP::weaken_metaclass( $self->name ) if $weaken;
609 sub _process_attribute {
610 my ( $self, $name, @args ) = @_;
612 @args = %{$args[0]} if scalar @args == 1 && ref($args[0]) eq 'HASH';
614 if (($name || '') =~ /^\+(.*)/) {
615 return $self->_process_inherited_attribute($1, @args);
618 return $self->_process_new_attribute($name, @args);
622 sub _process_new_attribute {
623 my ( $self, $name, @args ) = @_;
625 $self->attribute_metaclass->interpolate_class_and_new($name, @args);
628 sub _process_inherited_attribute {
629 my ($self, $attr_name, %options) = @_;
630 my $inherited_attr = $self->find_attribute_by_name($attr_name);
631 (defined $inherited_attr)
632 || $self->throw_error("Could not find an attribute by the name of '$attr_name' to inherit from in ${\$self->name}", data => $attr_name);
633 if ($inherited_attr->isa('Moose::Meta::Attribute')) {
634 return $inherited_attr->clone_and_inherit_options(%options);
638 # kind of a kludge to handle Class::MOP::Attributes
639 return $inherited_attr->Moose::Meta::Attribute::clone_and_inherit_options(%options);
643 # reinitialization support
645 sub _restore_metaobjects_from {
649 $self->SUPER::_restore_metaobjects_from($old_meta);
651 for my $role ( @{ $old_meta->roles } ) {
652 $self->add_role($role);
655 for my $application ( @{ $old_meta->_get_role_applications } ) {
656 $application->class($self);
657 $self->add_role_application ($application);
663 sub _immutable_options {
664 my ( $self, @args ) = @_;
666 $self->SUPER::_immutable_options(
667 inline_destructor => 1,
669 # Moose always does this when an attribute is created
670 inline_accessors => 0,
676 ## -------------------------------------------------
681 my ( $self, @args ) = @_;
682 local $error_level = ($error_level || 0) + 1;
683 $self->raise_error($self->create_error(@args));
686 sub _inline_throw_error {
687 my ( $self, $msg, $args ) = @_;
688 "\$meta->throw_error($msg" . ($args ? ", $args" : "") . ")"; # FIXME makes deparsing *REALLY* hard
692 my ( $self, @args ) = @_;
697 my ( $self, @args ) = @_;
701 local $error_level = ($error_level || 0 ) + 1;
703 if ( @args % 2 == 1 ) {
704 unshift @args, "message";
707 my %args = ( metaclass => $self, last_error => $@, @args );
709 $args{depth} += $error_level;
711 my $class = ref $self ? $self->error_class : "Moose::Error::Default";
713 Class::MOP::load_class($class);
716 Carp::caller_info($args{depth}),
723 # ABSTRACT: The Moose metaclass
731 This class is a subclass of L<Class::MOP::Class> that provides
732 additional Moose-specific functionality.
734 To really understand this class, you will need to start with the
735 L<Class::MOP::Class> documentation. This class can be understood as a
736 set of additional features on top of the basic feature provided by
741 C<Moose::Meta::Class> is a subclass of L<Class::MOP::Class>.
747 =item B<< Moose::Meta::Class->initialize($package_name, %options) >>
749 This overrides the parent's method in order to provide its own
750 defaults for the C<attribute_metaclass>, C<instance_metaclass>, and
751 C<method_metaclass> options.
753 These all default to the appropriate Moose class.
755 =item B<< Moose::Meta::Class->create($package_name, %options) >>
757 This overrides the parent's method in order to accept a C<roles>
758 option. This should be an array reference containing roles
759 that the class does, each optionally followed by a hashref of options
760 (C<-excludes> and C<-alias>).
762 my $metaclass = Moose::Meta::Class->create( 'New::Class', roles => [...] );
764 =item B<< Moose::Meta::Class->create_anon_class >>
766 This overrides the parent's method to accept a C<roles> option, just
769 It also accepts a C<cache> option. If this is true, then the anonymous
770 class will be cached based on its superclasses and roles. If an
771 existing anonymous class in the cache has the same superclasses and
772 roles, it will be reused.
774 my $metaclass = Moose::Meta::Class->create_anon_class(
775 superclasses => ['Foo'],
776 roles => [qw/Some Roles Go Here/],
780 Each entry in both the C<superclasses> and the C<roles> option can be
781 followed by a hash reference with arguments. The C<superclasses>
782 option can be supplied with a L<-version|Class::MOP/Class Loading
783 Options> option that ensures the loaded superclass satisfies the
784 required version. The C<role> option also takes the C<-version> as an
785 argument, but the option hash reference can also contain any other
786 role relevant values like exclusions or parameterized role arguments.
788 =item B<< $metaclass->make_immutable(%options) >>
790 This overrides the parent's method to add a few options. Specifically,
791 it uses the Moose-specific constructor and destructor classes, and
792 enables inlining the destructor.
794 Since Moose always inlines attributes, it sets the C<inline_accessors> option
797 =item B<< $metaclass->new_object(%params) >>
799 This overrides the parent's method in order to add support for
802 =item B<< $metaclass->superclasses(@superclasses) >>
804 This is the accessor allowing you to read or change the parents of
807 Each superclass can be followed by a hash reference containing a
808 L<-version|Class::MOP/Class Loading Options> value. If the version
809 requirement is not satisfied an error will be thrown.
811 =item B<< $metaclass->add_override_method_modifier($name, $sub) >>
813 This adds an C<override> method modifier to the package.
815 =item B<< $metaclass->add_augment_method_modifier($name, $sub) >>
817 This adds an C<augment> method modifier to the package.
819 =item B<< $metaclass->calculate_all_roles >>
821 This will return a unique array of C<Moose::Meta::Role> instances
822 which are attached to this class.
824 =item B<< $metaclass->calculate_all_roles_with_inheritance >>
826 This will return a unique array of C<Moose::Meta::Role> instances
827 which are attached to this class, and each of this class's ancestors.
829 =item B<< $metaclass->add_role($role) >>
831 This takes a L<Moose::Meta::Role> object, and adds it to the class's
832 list of roles. This I<does not> actually apply the role to the class.
834 =item B<< $metaclass->role_applications >>
836 Returns a list of L<Moose::Meta::Role::Application::ToClass>
837 objects, which contain the arguments to role application.
839 =item B<< $metaclass->add_role_application($application) >>
841 This takes a L<Moose::Meta::Role::Application::ToClass> object, and
842 adds it to the class's list of role applications. This I<does not>
843 actually apply any role to the class; it is only for tracking role
846 =item B<< $metaclass->does_role($role) >>
848 This returns a boolean indicating whether or not the class does the specified
849 role. The role provided can be either a role name or a L<Moose::Meta::Role>
850 object. This tests both the class and its parents.
852 =item B<< $metaclass->excludes_role($role_name) >>
854 A class excludes a role if it has already composed a role which
855 excludes the named role. This tests both the class and its parents.
857 =item B<< $metaclass->add_attribute($attr_name, %params|$params) >>
859 This overrides the parent's method in order to allow the parameters to
860 be provided as a hash reference.
862 =item B<< $metaclass->constructor_class($class_name) >>
864 =item B<< $metaclass->destructor_class($class_name) >>
866 These are the names of classes used when making a class immutable. These
867 default to L<Moose::Meta::Method::Constructor> and
868 L<Moose::Meta::Method::Destructor> respectively. These accessors are
869 read-write, so you can use them to change the class name.
871 =item B<< $metaclass->error_class($class_name) >>
873 The name of the class used to throw errors. This defaults to
874 L<Moose::Error::Default>, which generates an error with a stacktrace
875 just like C<Carp::confess>.
877 =item B<< $metaclass->throw_error($message, %extra) >>
879 Throws the error created by C<create_error> using C<raise_error>
885 See L<Moose/BUGS> for details on reporting bugs.