First pass at Moose 2.0 compatibility
[gitmo/MooseX-ClassAttribute.git] / lib / MooseX / ClassAttribute / Trait / Attribute.pm
CommitLineData
63fcc508 1package MooseX::ClassAttribute::Trait::Attribute;
bb70fe3a 2
3use strict;
4use warnings;
5
88b7f2c8 6use namespace::autoclean;
a1ec1ff1 7use Moose::Role;
bb70fe3a 8
a1ec1ff1 9# This is the worst role evar! Really, this should be a subclass,
10# because it overrides a lot of behavior. However, as a subclass it
8e988dc6 11# won't cooperate with _other_ subclasses.
bb70fe3a 12
9e2d0ef1 13around _process_options => sub {
a1ec1ff1 14 my $orig = shift;
bb70fe3a 15 my $class = shift;
16 my $name = shift;
17 my $options = shift;
18
19 confess 'A class attribute cannot be required'
20 if $options->{required};
21
a1ec1ff1 22 return $class->$orig( $name, $options );
23};
bb70fe3a 24
88b7f2c8 25around attach_to_class => sub {
a1ec1ff1 26 my $orig = shift;
bb70fe3a 27 my $self = shift;
28 my $meta = shift;
29
a1ec1ff1 30 $self->$orig($meta);
bb70fe3a 31
32 $self->_initialize($meta)
33 unless $self->is_lazy();
a1ec1ff1 34};
bb70fe3a 35
9e2d0ef1 36around detach_from_class => sub {
a1ec1ff1 37 my $orig = shift;
bb70fe3a 38 my $self = shift;
39 my $meta = shift;
40
41 $self->clear_value($meta);
42
a1ec1ff1 43 $self->$orig($meta);
44};
bb70fe3a 45
88b7f2c8 46sub _initialize {
6048a053 47 my $self = shift;
48 my $metaclass = shift;
bb70fe3a 49
88b7f2c8 50 if ( $self->has_default() ) {
d0785271 51 $self->set_value( undef, $self->default() );
bb70fe3a 52 }
88b7f2c8 53 elsif ( $self->has_builder() ) {
6048a053 54 $self->set_value( undef, $self->_call_builder( $metaclass->name() ) );
bb70fe3a 55 }
56}
57
9e2d0ef1 58around default => sub {
a1ec1ff1 59 my $orig = shift;
bb70fe3a 60 my $self = shift;
61
a1ec1ff1 62 my $default = $self->$orig();
bb70fe3a 63
88b7f2c8 64 if ( $self->is_default_a_coderef() ) {
bb70fe3a 65 return $default->( $self->associated_class() );
66 }
67
68 return $default;
a1ec1ff1 69};
bb70fe3a 70
9e2d0ef1 71around _call_builder => sub {
a1ec1ff1 72 shift;
bb70fe3a 73 my $self = shift;
74 my $class = shift;
75
76 my $builder = $self->builder();
77
78 return $class->$builder()
79 if $class->can( $self->builder );
80
81 confess( "$class does not support builder method '"
82 . $self->builder
83 . "' for attribute '"
84 . $self->name
85 . "'" );
a1ec1ff1 86};
bb70fe3a 87
9e2d0ef1 88around set_value => sub {
a1ec1ff1 89 shift;
88b7f2c8 90 my $self = shift;
91 shift; # ignoring instance or class name
92 my $value = shift;
bb70fe3a 93
88b7f2c8 94 $self->associated_class()
95 ->set_class_attribute_value( $self->name() => $value );
a1ec1ff1 96};
bb70fe3a 97
9e2d0ef1 98around get_value => sub {
a1ec1ff1 99 shift;
88b7f2c8 100 my $self = shift;
bb70fe3a 101
88b7f2c8 102 return $self->associated_class()
103 ->get_class_attribute_value( $self->name() );
a1ec1ff1 104};
bb70fe3a 105
9e2d0ef1 106around has_value => sub {
a1ec1ff1 107 shift;
88b7f2c8 108 my $self = shift;
bb70fe3a 109
88b7f2c8 110 return $self->associated_class()
111 ->has_class_attribute_value( $self->name() );
a1ec1ff1 112};
bb70fe3a 113
9e2d0ef1 114around clear_value => sub {
a1ec1ff1 115 shift;
88b7f2c8 116 my $self = shift;
bb70fe3a 117
88b7f2c8 118 return $self->associated_class()
119 ->clear_class_attribute_value( $self->name() );
a1ec1ff1 120};
bb70fe3a 121
28c23808 122if ( $Moose::VERSION < 1.99 ) {
123 around inline_get => sub {
124 shift;
125 my $self = shift;
126
127 return $self->associated_class()
128 ->inline_get_class_slot_value( $self->slots() );
129 };
130
131 around inline_set => sub {
132 shift;
133 my $self = shift;
134 shift;
135 my $value = shift;
136
137 my $meta = $self->associated_class();
138
139 my $code
140 = $meta->inline_set_class_slot_value( $self->slots(), $value )
141 . ";";
142 $code
143 .= $meta->inline_weaken_class_slot_value( $self->slots(), $value )
144 . " if ref $value;"
145 if $self->is_weak_ref();
146
147 return $code;
148 };
149
150 around inline_has => sub {
151 shift;
152 my $self = shift;
153
154 return $self->associated_class()
155 ->inline_is_class_slot_initialized( $self->slots() );
156 };
157
158 around inline_clear => sub {
159 shift;
160 my $self = shift;
161
162 return $self->associated_class()
163 ->inline_deinitialize_class_slot( $self->slots() );
164 };
165}
166else {
167 around _inline_instance_get => sub {
168 shift;
169 my $self = shift;
170
171 return $self->associated_class()
172 ->inline_get_class_slot_value( $self->slots() );
173 };
174
175 around _inline_instance_set => sub {
176 shift;
177 my $self = shift;
178 shift;
179 my $value = shift;
180
181 return $self->associated_class()
182 ->inline_set_class_slot_value( $self->slots(), $value );
183 };
184
185 around _inline_instance_has => sub {
186 shift;
187 my $self = shift;
188
189 return $self->associated_class()
190 ->inline_is_class_slot_initialized( $self->slots() );
191 };
192
193 around _inline_instance_clear => sub {
194 shift;
195 my $self = shift;
196
197 return $self->associated_class()
198 ->inline_deinitialize_class_slot( $self->slots() );
199 };
200
201 around _inline_weaken_value => sub {
202 shift;
203 my $self = shift;
204 shift;
205 my $value = shift;
206
207 return unless $self->is_weak_ref();
208
209 return (
210 $self->associated_class->inline_weaken_class_slot_value(
211 $self->slots(), $value
212 ),
213 'if ref ' . $value . ';',
214 );
215 };
216}
935982fc 217
bb70fe3a 2181;
7a4a3b1e 219
0d0bf8c3 220# ABSTRACT: A trait for class attributes
221
7a4a3b1e 222__END__
223
224=pod
225
7a4a3b1e 226=head1 DESCRIPTION
227
228This role modifies the behavior of class attributes in various
229ways. It really should be a subclass of C<Moose::Meta::Attribute>, but
230if it were then it couldn't be combined with other attribute
231metaclasses, like C<MooseX::AttributeHelpers>.
232
233There are no new public methods implemented by this role. All it does
234is change the behavior of a number of existing methods.
235
7a4a3b1e 236=head1 BUGS
237
238See L<MooseX::ClassAttribute> for details.
239
7a4a3b1e 240=cut