1 package Moose::Meta::Role::Attribute;
7 use List::MoreUtils 'all';
8 use Scalar::Util 'blessed', 'weaken';
10 use base 'Moose::Meta::Mixin::AttributeCore', 'Class::MOP::Object';
12 __PACKAGE__->meta->add_attribute(
14 reader => 'metaclass',
15 Class::MOP::_definition_context(),
19 __PACKAGE__->meta->add_attribute(
20 'associated_role' => (
21 reader => 'associated_role',
22 Class::MOP::_definition_context(),
26 __PACKAGE__->meta->add_attribute(
28 reader => '_original_role',
29 Class::MOP::_definition_context(),
33 __PACKAGE__->meta->add_attribute(
36 Class::MOP::_definition_context(),
40 __PACKAGE__->meta->add_attribute(
41 'original_options' => (
42 reader => 'original_options',
43 Class::MOP::_definition_context(),
48 my ( $class, $name, %options ) = @_;
51 || confess "You must provide a name for the attribute";
53 my $role = delete $options{_original_role};
57 original_options => \%options,
58 _original_role => $role,
64 my ( $self, $role ) = @_;
66 ( blessed($role) && $role->isa('Moose::Meta::Role') )
68 "You must pass a Moose::Meta::Role instance (or a subclass)";
70 weaken( $self->{'associated_role'} = $role );
76 return $self->_original_role || $self->associated_role;
79 sub attribute_for_class {
82 my $metaclass = $self->original_role->applied_attribute_metaclass;
84 return $metaclass->interpolate_class_and_new(
85 $self->name => %{ $self->original_options } );
91 my $role = $self->original_role;
93 return ( ref $self )->new(
95 %{ $self->original_options },
96 _original_role => $role,
104 my $self_options = $self->original_options;
105 my $other_options = $attr->original_options;
108 unless ( join q{|}, sort keys %{$self_options} ) eq ( join q{|}, sort keys %{$other_options} );
110 for my $key ( keys %{$self_options} ) {
111 return 0 if defined $self_options->{$key} && ! defined $other_options->{$key};
112 return 0 if ! defined $self_options->{$key} && defined $other_options->{$key};
114 next if all { ! defined } $self_options->{$key}, $other_options->{$key};
116 return 0 unless $self_options->{$key} eq $other_options->{$key};
124 # ABSTRACT: The Moose attribute metaclass for Roles
132 This class implements the API for attributes in roles. Attributes in roles are
133 more like attribute prototypes than full blown attributes. While they are
134 introspectable, they have very little behavior.
138 This class provides the following methods:
142 =item B<< Moose::Meta::Role::Attribute->new(...) >>
144 This method accepts all the options that would be passed to the constructor
145 for L<Moose::Meta::Attribute>.
147 =item B<< $attr->metaclass >>
149 =item B<< $attr->is >>
151 Returns the option as passed to the constructor.
153 =item B<< $attr->associated_role >>
155 Returns the L<Moose::Meta::Role> to which this attribute belongs, if any.
157 =item B<< $attr->original_role >>
159 Returns the L<Moose::Meta::Role> in which this attribute was first
160 defined. This may not be the same as the value C<associated_role()> in the
161 case of composite role, or the case where one role consumes other roles.
163 =item B<< $attr->original_options >>
165 Returns a hash reference of options passed to the constructor. This is used
166 when creating a L<Moose::Meta::Attribute> object from this object.
168 =item B<< $attr->attach_to_role($role) >>
170 Attaches the attribute to the given L<Moose::Meta::Role>.
172 =item B<< $attr->attribute_for_class($metaclass) >>
174 Given an attribute metaclass name, this method calls C<<
175 $metaclass->interpolate_class_and_new >> to construct an attribute object
176 which can be added to a L<Moose::Meta::Class>.
178 =item B<< $attr->clone >>
180 Creates a new object identical to the object on which the method is called.
182 =item B<< $attr->is_same_as($other_attr) >>
184 Compares two role attributes and returns true if they are identical.
188 In addition, this class implements all informational predicates implements by
189 L<Moose::Meta::Attribute> (and L<Class::MOP::Attribute>).
193 See L<Moose/BUGS> for details on reporting bugs.