fix attr ->default method to work like it does for regular attributes. only call...
[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
549cbfd2 25after attach_to_class => sub {
bb70fe3a 26 my $self = shift;
27 my $meta = shift;
28
bb70fe3a 29 $self->_initialize($meta)
30 unless $self->is_lazy();
a1ec1ff1 31};
bb70fe3a 32
549cbfd2 33before detach_from_class => sub {
bb70fe3a 34 my $self = shift;
35 my $meta = shift;
36
37 $self->clear_value($meta);
a1ec1ff1 38};
bb70fe3a 39
88b7f2c8 40sub _initialize {
6048a053 41 my $self = shift;
42 my $metaclass = shift;
bb70fe3a 43
88b7f2c8 44 if ( $self->has_default() ) {
e5fa95ba 45 $self->set_value( undef,
46 $self->default( $self->associated_class() ) );
bb70fe3a 47 }
88b7f2c8 48 elsif ( $self->has_builder() ) {
6048a053 49 $self->set_value( undef, $self->_call_builder( $metaclass->name() ) );
bb70fe3a 50 }
51}
52
9e2d0ef1 53around default => sub {
a1ec1ff1 54 my $orig = shift;
bb70fe3a 55 my $self = shift;
56
a1ec1ff1 57 my $default = $self->$orig();
bb70fe3a 58
e5fa95ba 59 if ( $self->is_default_a_coderef() && @_ ) {
60 return $default->(@_);
bb70fe3a 61 }
62
63 return $default;
a1ec1ff1 64};
bb70fe3a 65
9e2d0ef1 66around _call_builder => sub {
a1ec1ff1 67 shift;
bb70fe3a 68 my $self = shift;
69 my $class = shift;
70
71 my $builder = $self->builder();
72
73 return $class->$builder()
74 if $class->can( $self->builder );
75
76 confess( "$class does not support builder method '"
77 . $self->builder
78 . "' for attribute '"
79 . $self->name
80 . "'" );
a1ec1ff1 81};
bb70fe3a 82
9e2d0ef1 83around set_value => sub {
a1ec1ff1 84 shift;
88b7f2c8 85 my $self = shift;
86 shift; # ignoring instance or class name
87 my $value = shift;
bb70fe3a 88
88b7f2c8 89 $self->associated_class()
90 ->set_class_attribute_value( $self->name() => $value );
a1ec1ff1 91};
bb70fe3a 92
9e2d0ef1 93around get_value => sub {
a1ec1ff1 94 shift;
88b7f2c8 95 my $self = shift;
bb70fe3a 96
88b7f2c8 97 return $self->associated_class()
98 ->get_class_attribute_value( $self->name() );
a1ec1ff1 99};
bb70fe3a 100
9e2d0ef1 101around has_value => sub {
a1ec1ff1 102 shift;
88b7f2c8 103 my $self = shift;
bb70fe3a 104
88b7f2c8 105 return $self->associated_class()
106 ->has_class_attribute_value( $self->name() );
a1ec1ff1 107};
bb70fe3a 108
9e2d0ef1 109around clear_value => sub {
a1ec1ff1 110 shift;
88b7f2c8 111 my $self = shift;
bb70fe3a 112
88b7f2c8 113 return $self->associated_class()
114 ->clear_class_attribute_value( $self->name() );
a1ec1ff1 115};
bb70fe3a 116
28c23808 117if ( $Moose::VERSION < 1.99 ) {
118 around inline_get => sub {
119 shift;
120 my $self = shift;
121
122 return $self->associated_class()
a5ed69bc 123 ->_inline_get_class_slot_value( $self->slots() );
28c23808 124 };
125
126 around inline_set => sub {
127 shift;
128 my $self = shift;
129 shift;
130 my $value = shift;
131
132 my $meta = $self->associated_class();
133
134 my $code
a5ed69bc 135 = $meta->_inline_set_class_slot_value( $self->slots(), $value )
28c23808 136 . ";";
137 $code
a5ed69bc 138 .= $meta->_inline_weaken_class_slot_value( $self->slots(), $value )
28c23808 139 . " if ref $value;"
140 if $self->is_weak_ref();
141
142 return $code;
143 };
144
145 around inline_has => sub {
146 shift;
147 my $self = shift;
148
149 return $self->associated_class()
a5ed69bc 150 ->_inline_is_class_slot_initialized( $self->slots() );
28c23808 151 };
152
153 around inline_clear => sub {
154 shift;
155 my $self = shift;
156
157 return $self->associated_class()
a5ed69bc 158 ->_inline_deinitialize_class_slot( $self->slots() );
28c23808 159 };
160}
161else {
162 around _inline_instance_get => sub {
163 shift;
164 my $self = shift;
165
166 return $self->associated_class()
a5ed69bc 167 ->_inline_get_class_slot_value( $self->slots() );
28c23808 168 };
169
170 around _inline_instance_set => sub {
171 shift;
172 my $self = shift;
173 shift;
174 my $value = shift;
175
176 return $self->associated_class()
a5ed69bc 177 ->_inline_set_class_slot_value( $self->slots(), $value );
28c23808 178 };
179
180 around _inline_instance_has => sub {
181 shift;
182 my $self = shift;
183
184 return $self->associated_class()
a5ed69bc 185 ->_inline_is_class_slot_initialized( $self->slots() );
28c23808 186 };
187
188 around _inline_instance_clear => sub {
189 shift;
190 my $self = shift;
191
192 return $self->associated_class()
a5ed69bc 193 ->_inline_deinitialize_class_slot( $self->slots() );
28c23808 194 };
195
196 around _inline_weaken_value => sub {
197 shift;
198 my $self = shift;
199 shift;
200 my $value = shift;
201
202 return unless $self->is_weak_ref();
203
204 return (
a5ed69bc 205 $self->associated_class->_inline_weaken_class_slot_value(
28c23808 206 $self->slots(), $value
207 ),
208 'if ref ' . $value . ';',
209 );
210 };
211}
935982fc 212
bb70fe3a 2131;
7a4a3b1e 214
0d0bf8c3 215# ABSTRACT: A trait for class attributes
216
7a4a3b1e 217__END__
218
219=pod
220
7a4a3b1e 221=head1 DESCRIPTION
222
223This role modifies the behavior of class attributes in various
224ways. It really should be a subclass of C<Moose::Meta::Attribute>, but
225if it were then it couldn't be combined with other attribute
226metaclasses, like C<MooseX::AttributeHelpers>.
227
228There are no new public methods implemented by this role. All it does
229is change the behavior of a number of existing methods.
230
7a4a3b1e 231=head1 BUGS
232
233See L<MooseX::ClassAttribute> for details.
234
7a4a3b1e 235=cut