Use dzil Authority plugin - remove $AUTHORITY from code
[gitmo/Moose.git] / lib / Moose / Meta / Role / Attribute.pm
CommitLineData
f785aad8 1package Moose::Meta::Role::Attribute;
2
3use strict;
4use warnings;
5
6use Carp 'confess';
7use List::MoreUtils 'all';
8use Scalar::Util 'blessed', 'weaken';
9
be83e895 10use base 'Moose::Meta::Mixin::AttributeCore', 'Class::MOP::Object';
f785aad8 11
12__PACKAGE__->meta->add_attribute(
13 'metaclass' => (
14 reader => 'metaclass',
15 )
16);
17
18__PACKAGE__->meta->add_attribute(
19 'associated_role' => (
20 reader => 'associated_role',
21 )
22);
23
24__PACKAGE__->meta->add_attribute(
25 'is' => (
26 reader => 'is',
27 )
28);
29
30__PACKAGE__->meta->add_attribute(
31 'original_options' => (
32 reader => 'original_options',
33 )
34);
35
36sub new {
37 my ( $class, $name, %options ) = @_;
38
39 (defined $name)
40 || confess "You must provide a name for the attribute";
41
42 return bless {
43 name => $name,
44 original_options => \%options,
45 %options,
46 }, $class;
47}
48
49sub attach_to_role {
50 my ( $self, $role ) = @_;
51
52 ( blessed($role) && $role->isa('Moose::Meta::Role') )
53 || confess
54 "You must pass a Moose::Meta::Role instance (or a subclass)";
55
56 weaken( $self->{'associated_role'} = $role );
57}
58
59sub attribute_for_class {
60 my $self = shift;
61 my $metaclass = shift;
62
63 return $metaclass->interpolate_class_and_new(
64 $self->name => %{ $self->original_options } );
65}
66
67sub clone {
68 my $self = shift;
69
70 return ( ref $self )->new( $self->name, %{ $self->original_options } );
71}
72
73sub is_same_as {
74 my $self = shift;
75 my $attr = shift;
76
77 my $self_options = $self->original_options;
78 my $other_options = $attr->original_options;
79
80 return 0
81 unless ( join q{|}, sort keys %{$self_options} ) eq ( join q{|}, sort keys %{$other_options} );
82
83 for my $key ( keys %{$self_options} ) {
84 return 0 if defined $self_options->{$key} && ! defined $other_options->{$key};
85 return 0 if ! defined $self_options->{$key} && defined $other_options->{$key};
86
87 next if all { ! defined } $self_options->{$key}, $other_options->{$key};
88
89 return 0 unless $self_options->{$key} eq $other_options->{$key};
90 }
91
92 return 1;
93}
94
951;
96
97=pod
98
f785aad8 99=head1 DESCRIPTION
100
101This class implements the API for attributes in roles. Attributes in roles are
102more like attribute prototypes than full blown attributes. While they are
103introspectable, they have very little behavior.
104
105=head1 METHODS
106
107This class provides the following methods:
108
109=over 4
110
111=item B<< Moose::Meta::Role::Attribute->new(...) >>
112
113This method accepts all the options that would be passed to the constructor
114for L<Moose::Meta::Attribute>.
115
116=item B<< $attr->metaclass >>
117
118=item B<< $attr->is >>
119
120Returns the option as passed to the constructor.
121
122=item B<< $attr->associated_role >>
123
124Returns the L<Moose::Meta::Role> to which this attribute belongs, if any.
125
126=item B<< $attr->original_options >>
127
128Returns a hash reference of options passed to the constructor. This is used
129when creating a L<Moose::Meta::Attribute> object from this object.
130
131=item B<< $attr->attach_to_role($role) >>
132
133Attaches the attribute to the given L<Moose::Meta::Role>.
134
135=item B<< $attr->attribute_for_class($metaclass) >>
136
137Given an attribute metaclass name, this method calls C<<
138$metaclass->interpolate_class_and_new >> to construct an attribute object
139which can be added to a L<Moose::Meta::Class>.
140
141=item B<< $attr->clone >>
142
143Creates a new object identical to the object on which the method is called.
144
145=item B<< $attr->is_same_as($other_attr) >>
146
147Compares two role attributes and returns true if they are identical.
148
149=back
150
151In addition, this class implements all informational predicates implements by
152L<Moose::Meta::Attribute> (and L<Class::MOP::Attribute>).
153
154=head1 BUGS
155
d4048ef3 156See L<Moose/BUGS> for details on reporting bugs.
f785aad8 157
f785aad8 158=cut