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',
18 __PACKAGE__->meta->add_attribute(
19 'associated_role' => (
20 reader => 'associated_role',
24 __PACKAGE__->meta->add_attribute(
26 reader => '_original_role',
30 __PACKAGE__->meta->add_attribute(
36 __PACKAGE__->meta->add_attribute(
37 'original_options' => (
38 reader => 'original_options',
43 my ( $class, $name, %options ) = @_;
46 || confess "You must provide a name for the attribute";
48 my $role = delete $options{_original_role};
52 original_options => \%options,
53 _original_role => $role,
59 my ( $self, $role ) = @_;
61 ( blessed($role) && $role->isa('Moose::Meta::Role') )
63 "You must pass a Moose::Meta::Role instance (or a subclass)";
65 weaken( $self->{'associated_role'} = $role );
71 return $self->_original_role || $self->associated_role;
74 sub attribute_for_class {
77 my $metaclass = $self->original_role->applied_attribute_metaclass;
79 return $metaclass->interpolate_class_and_new(
80 $self->name => %{ $self->original_options } );
86 my $role = $self->original_role;
88 return ( ref $self )->new(
90 %{ $self->original_options },
91 _original_role => $role,
99 my $self_options = $self->original_options;
100 my $other_options = $attr->original_options;
103 unless ( join q{|}, sort keys %{$self_options} ) eq ( join q{|}, sort keys %{$other_options} );
105 for my $key ( keys %{$self_options} ) {
106 return 0 if defined $self_options->{$key} && ! defined $other_options->{$key};
107 return 0 if ! defined $self_options->{$key} && defined $other_options->{$key};
109 next if all { ! defined } $self_options->{$key}, $other_options->{$key};
111 return 0 unless $self_options->{$key} eq $other_options->{$key};
119 # ABSTRACT: The Moose attribute metaclass for Roles
127 This class implements the API for attributes in roles. Attributes in roles are
128 more like attribute prototypes than full blown attributes. While they are
129 introspectable, they have very little behavior.
133 This class provides the following methods:
137 =item B<< Moose::Meta::Role::Attribute->new(...) >>
139 This method accepts all the options that would be passed to the constructor
140 for L<Moose::Meta::Attribute>.
142 =item B<< $attr->metaclass >>
144 =item B<< $attr->is >>
146 Returns the option as passed to the constructor.
148 =item B<< $attr->associated_role >>
150 Returns the L<Moose::Meta::Role> to which this attribute belongs, if any.
152 =item B<< $attr->original_role >>
154 Returns the L<Moose::Meta::Role> in which this attribute was first
155 defined. This may not be the same as the value C<associated_role()> in the
156 case of composite role, or the case where one role consumes other roles.
158 =item B<< $attr->original_options >>
160 Returns a hash reference of options passed to the constructor. This is used
161 when creating a L<Moose::Meta::Attribute> object from this object.
163 =item B<< $attr->attach_to_role($role) >>
165 Attaches the attribute to the given L<Moose::Meta::Role>.
167 =item B<< $attr->attribute_for_class($metaclass) >>
169 Given an attribute metaclass name, this method calls C<<
170 $metaclass->interpolate_class_and_new >> to construct an attribute object
171 which can be added to a L<Moose::Meta::Class>.
173 =item B<< $attr->clone >>
175 Creates a new object identical to the object on which the method is called.
177 =item B<< $attr->is_same_as($other_attr) >>
179 Compares two role attributes and returns true if they are identical.
183 In addition, this class implements all informational predicates implements by
184 L<Moose::Meta::Attribute> (and L<Class::MOP::Attribute>).
188 See L<Moose/BUGS> for details on reporting bugs.