Changes for next release of Moose
[gitmo/MooseX-ClassAttribute.git] / lib / MooseX / ClassAttribute / Trait / Attribute.pm
CommitLineData
63fcc508 1package MooseX::ClassAttribute::Trait::Attribute;
bb70fe3a 2
3use strict;
4use warnings;
5
6use MooseX::ClassAttribute::Meta::Method::Accessor;
7
88b7f2c8 8use namespace::autoclean;
a1ec1ff1 9use Moose::Role;
bb70fe3a 10
a1ec1ff1 11# This is the worst role evar! Really, this should be a subclass,
12# because it overrides a lot of behavior. However, as a subclass it
8e988dc6 13# won't cooperate with _other_ subclasses.
bb70fe3a 14
88b7f2c8 15around '_process_options' => sub {
a1ec1ff1 16 my $orig = shift;
bb70fe3a 17 my $class = shift;
18 my $name = shift;
19 my $options = shift;
20
21 confess 'A class attribute cannot be required'
22 if $options->{required};
23
a1ec1ff1 24 return $class->$orig( $name, $options );
25};
bb70fe3a 26
88b7f2c8 27around attach_to_class => sub {
a1ec1ff1 28 my $orig = shift;
bb70fe3a 29 my $self = shift;
30 my $meta = shift;
31
a1ec1ff1 32 $self->$orig($meta);
bb70fe3a 33
34 $self->_initialize($meta)
35 unless $self->is_lazy();
a1ec1ff1 36};
bb70fe3a 37
88b7f2c8 38around 'detach_from_class' => sub {
a1ec1ff1 39 my $orig = shift;
bb70fe3a 40 my $self = shift;
41 my $meta = shift;
42
43 $self->clear_value($meta);
44
a1ec1ff1 45 $self->$orig($meta);
46};
bb70fe3a 47
88b7f2c8 48sub _initialize {
6048a053 49 my $self = shift;
50 my $metaclass = shift;
bb70fe3a 51
88b7f2c8 52 if ( $self->has_default() ) {
d0785271 53 $self->set_value( undef, $self->default() );
bb70fe3a 54 }
88b7f2c8 55 elsif ( $self->has_builder() ) {
6048a053 56 $self->set_value( undef, $self->_call_builder( $metaclass->name() ) );
bb70fe3a 57 }
58}
59
88b7f2c8 60around 'default' => sub {
a1ec1ff1 61 my $orig = shift;
bb70fe3a 62 my $self = shift;
63
a1ec1ff1 64 my $default = $self->$orig();
bb70fe3a 65
88b7f2c8 66 if ( $self->is_default_a_coderef() ) {
bb70fe3a 67 return $default->( $self->associated_class() );
68 }
69
70 return $default;
a1ec1ff1 71};
bb70fe3a 72
88b7f2c8 73around '_call_builder' => sub {
a1ec1ff1 74 shift;
bb70fe3a 75 my $self = shift;
76 my $class = shift;
77
78 my $builder = $self->builder();
79
80 return $class->$builder()
81 if $class->can( $self->builder );
82
83 confess( "$class does not support builder method '"
84 . $self->builder
85 . "' for attribute '"
86 . $self->name
87 . "'" );
a1ec1ff1 88};
bb70fe3a 89
88b7f2c8 90around 'set_value' => sub {
a1ec1ff1 91 shift;
88b7f2c8 92 my $self = shift;
93 shift; # ignoring instance or class name
94 my $value = shift;
bb70fe3a 95
88b7f2c8 96 $self->associated_class()
97 ->set_class_attribute_value( $self->name() => $value );
a1ec1ff1 98};
bb70fe3a 99
88b7f2c8 100around 'get_value' => sub {
a1ec1ff1 101 shift;
88b7f2c8 102 my $self = shift;
bb70fe3a 103
88b7f2c8 104 return $self->associated_class()
105 ->get_class_attribute_value( $self->name() );
a1ec1ff1 106};
bb70fe3a 107
88b7f2c8 108around 'has_value' => sub {
a1ec1ff1 109 shift;
88b7f2c8 110 my $self = shift;
bb70fe3a 111
88b7f2c8 112 return $self->associated_class()
113 ->has_class_attribute_value( $self->name() );
a1ec1ff1 114};
bb70fe3a 115
88b7f2c8 116around 'clear_value' => sub {
a1ec1ff1 117 shift;
88b7f2c8 118 my $self = shift;
bb70fe3a 119
88b7f2c8 120 return $self->associated_class()
121 ->clear_class_attribute_value( $self->name() );
a1ec1ff1 122};
bb70fe3a 123
935982fc 124around 'inline_get' => sub {
125 shift;
126 my $self = shift;
127
128 return $self->associated_class()
129 ->inline_get_class_slot_value( $self->slots() );
130};
131
132around 'inline_set' => sub {
133 shift;
134 my $self = shift;
135 shift;
136 my $value = shift;
137
138 my $meta = $self->associated_class();
139
140 my $code
141 = $meta->inline_set_class_slot_value( $self->slots(), $value ) . ";";
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
150around '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
158around 'inline_clear' => sub {
159 shift;
160 my $self = shift;
161
162 return $self->associated_class()
163 ->inline_deinitialize_class_slot( $self->slots() );
164};
165
bb70fe3a 1661;
7a4a3b1e 167
0d0bf8c3 168# ABSTRACT: A trait for class attributes
169
7a4a3b1e 170__END__
171
172=pod
173
7a4a3b1e 174=head1 DESCRIPTION
175
176This role modifies the behavior of class attributes in various
177ways. It really should be a subclass of C<Moose::Meta::Attribute>, but
178if it were then it couldn't be combined with other attribute
179metaclasses, like C<MooseX::AttributeHelpers>.
180
181There are no new public methods implemented by this role. All it does
182is change the behavior of a number of existing methods.
183
7a4a3b1e 184=head1 BUGS
185
186See L<MooseX::ClassAttribute> for details.
187
7a4a3b1e 188=cut