1 package Moose::Meta::Role::Attribute;
6 use List::MoreUtils 'all';
7 use Scalar::Util 'blessed', 'weaken';
9 use base 'Moose::Meta::Mixin::AttributeCore', 'Class::MOP::Object';
11 __PACKAGE__->meta->add_attribute(
13 reader => 'metaclass',
14 Class::MOP::_definition_context(),
18 __PACKAGE__->meta->add_attribute(
19 'associated_role' => (
20 reader => 'associated_role',
21 Class::MOP::_definition_context(),
25 __PACKAGE__->meta->add_attribute(
27 reader => '_original_role',
28 Class::MOP::_definition_context(),
32 __PACKAGE__->meta->add_attribute(
35 Class::MOP::_definition_context(),
39 __PACKAGE__->meta->add_attribute(
40 'original_options' => (
41 reader => 'original_options',
42 Class::MOP::_definition_context(),
47 my ( $class, $name, %options ) = @_;
50 || Moose::Util::throw "You must provide a name for the attribute";
52 my $role = delete $options{_original_role};
56 original_options => \%options,
57 _original_role => $role,
63 my ( $self, $role ) = @_;
65 ( blessed($role) && $role->isa('Moose::Meta::Role') )
67 "You must pass a Moose::Meta::Role instance (or a subclass)";
69 weaken( $self->{'associated_role'} = $role );
75 return $self->_original_role || $self->associated_role;
78 sub attribute_for_class {
81 my $metaclass = $self->original_role->applied_attribute_metaclass;
83 return $metaclass->interpolate_class_and_new(
84 $self->name => %{ $self->original_options } );
90 my $role = $self->original_role;
92 return ( ref $self )->new(
94 %{ $self->original_options },
95 _original_role => $role,
103 my $self_options = $self->original_options;
104 my $other_options = $attr->original_options;
107 unless ( join q{|}, sort keys %{$self_options} ) eq ( join q{|}, sort keys %{$other_options} );
109 for my $key ( keys %{$self_options} ) {
110 return 0 if defined $self_options->{$key} && ! defined $other_options->{$key};
111 return 0 if ! defined $self_options->{$key} && defined $other_options->{$key};
113 next if all { ! defined } $self_options->{$key}, $other_options->{$key};
115 return 0 unless $self_options->{$key} eq $other_options->{$key};
123 # ABSTRACT: The Moose attribute metaclass for Roles
131 This class implements the API for attributes in roles. Attributes in roles are
132 more like attribute prototypes than full blown attributes. While they are
133 introspectable, they have very little behavior.
137 This class provides the following methods:
141 =item B<< Moose::Meta::Role::Attribute->new(...) >>
143 This method accepts all the options that would be passed to the constructor
144 for L<Moose::Meta::Attribute>.
146 =item B<< $attr->metaclass >>
148 =item B<< $attr->is >>
150 Returns the option as passed to the constructor.
152 =item B<< $attr->associated_role >>
154 Returns the L<Moose::Meta::Role> to which this attribute belongs, if any.
156 =item B<< $attr->original_role >>
158 Returns the L<Moose::Meta::Role> in which this attribute was first
159 defined. This may not be the same as the value C<associated_role()> in the
160 case of composite role, or the case where one role consumes other roles.
162 =item B<< $attr->original_options >>
164 Returns a hash reference of options passed to the constructor. This is used
165 when creating a L<Moose::Meta::Attribute> object from this object.
167 =item B<< $attr->attach_to_role($role) >>
169 Attaches the attribute to the given L<Moose::Meta::Role>.
171 =item B<< $attr->attribute_for_class($metaclass) >>
173 Given an attribute metaclass name, this method calls C<<
174 $metaclass->interpolate_class_and_new >> to construct an attribute object
175 which can be added to a L<Moose::Meta::Class>.
177 =item B<< $attr->clone >>
179 Creates a new object identical to the object on which the method is called.
181 =item B<< $attr->is_same_as($other_attr) >>
183 Compares two role attributes and returns true if they are identical.
187 In addition, this class implements all informational predicates implements by
188 L<Moose::Meta::Attribute> (and L<Class::MOP::Attribute>).
192 See L<Moose/BUGS> for details on reporting bugs.