Add built local::lib
[catagits/Gitalist.git] / local-lib5 / lib / perl5 / i486-linux-gnu-thread-multi / Class / MOP / Method / Accessor.pm
CommitLineData
3fea05b9 1
2package Class::MOP::Method::Accessor;
3
4use strict;
5use warnings;
6
7use Carp 'confess';
8use Scalar::Util 'blessed', 'weaken';
9
10our $VERSION = '0.95';
11$VERSION = eval $VERSION;
12our $AUTHORITY = 'cpan:STEVAN';
13
14use base 'Class::MOP::Method::Generated';
15
16sub new {
17 my $class = shift;
18 my %options = @_;
19
20 (exists $options{attribute})
21 || confess "You must supply an attribute to construct with";
22
23 (exists $options{accessor_type})
24 || confess "You must supply an accessor_type to construct with";
25
26 (blessed($options{attribute}) && $options{attribute}->isa('Class::MOP::Attribute'))
27 || confess "You must supply an attribute which is a 'Class::MOP::Attribute' instance";
28
29 ($options{package_name} && $options{name})
30 || confess "You must supply the package_name and name parameters $Class::MOP::Method::UPGRADE_ERROR_TEXT";
31
32 my $self = $class->_new(\%options);
33
34 # we don't want this creating
35 # a cycle in the code, if not
36 # needed
37 weaken($self->{'attribute'});
38
39 $self->_initialize_body;
40
41 return $self;
42}
43
44sub _new {
45 my $class = shift;
46
47 return Class::MOP::Class->initialize($class)->new_object(@_)
48 if $class ne __PACKAGE__;
49
50 my $params = @_ == 1 ? $_[0] : {@_};
51
52 return bless {
53 # inherited from Class::MOP::Method
54 body => $params->{body},
55 associated_metaclass => $params->{associated_metaclass},
56 package_name => $params->{package_name},
57 name => $params->{name},
58 original_method => $params->{original_method},
59
60 # inherit from Class::MOP::Generated
61 is_inline => $params->{is_inline} || 0,
62 definition_context => $params->{definition_context},
63
64 # defined in this class
65 attribute => $params->{attribute},
66 accessor_type => $params->{accessor_type},
67 } => $class;
68}
69
70## accessors
71
72sub associated_attribute { (shift)->{'attribute'} }
73sub accessor_type { (shift)->{'accessor_type'} }
74
75## factory
76
77sub _initialize_body {
78 my $self = shift;
79
80 my $method_name = join "_" => (
81 '_generate',
82 $self->accessor_type,
83 'method',
84 ($self->is_inline ? 'inline' : ())
85 );
86
87 $self->{'body'} = $self->$method_name();
88}
89
90## generators
91
92sub _generate_accessor_method {
93 my $attr = (shift)->associated_attribute;
94 return sub {
95 $attr->set_value($_[0], $_[1]) if scalar(@_) == 2;
96 $attr->get_value($_[0]);
97 };
98}
99
100sub _generate_reader_method {
101 my $attr = (shift)->associated_attribute;
102 return sub {
103 confess "Cannot assign a value to a read-only accessor" if @_ > 1;
104 $attr->get_value($_[0]);
105 };
106}
107
108
109sub _generate_writer_method {
110 my $attr = (shift)->associated_attribute;
111 return sub {
112 $attr->set_value($_[0], $_[1]);
113 };
114}
115
116sub _generate_predicate_method {
117 my $attr = (shift)->associated_attribute;
118 return sub {
119 $attr->has_value($_[0])
120 };
121}
122
123sub _generate_clearer_method {
124 my $attr = (shift)->associated_attribute;
125 return sub {
126 $attr->clear_value($_[0])
127 };
128}
129
130## Inline methods
131
132sub _generate_accessor_method_inline {
133 my $self = shift;
134 my $attr = $self->associated_attribute;
135 my $attr_name = $attr->name;
136 my $meta_instance = $attr->associated_class->instance_metaclass;
137
138 my ( $code, $e ) = $self->_eval_closure(
139 {},
140 'sub {'
141 . $meta_instance->inline_set_slot_value('$_[0]', $attr_name, '$_[1]')
142 . ' if scalar(@_) == 2; '
143 . $meta_instance->inline_get_slot_value('$_[0]', $attr_name)
144 . '}'
145 );
146 confess "Could not generate inline accessor because : $e" if $e;
147
148 return $code;
149}
150
151sub _generate_reader_method_inline {
152 my $self = shift;
153 my $attr = $self->associated_attribute;
154 my $attr_name = $attr->name;
155 my $meta_instance = $attr->associated_class->instance_metaclass;
156
157 my ( $code, $e ) = $self->_eval_closure(
158 {},
159 'sub {'
160 . 'confess "Cannot assign a value to a read-only accessor" if @_ > 1;'
161 . $meta_instance->inline_get_slot_value('$_[0]', $attr_name)
162 . '}'
163 );
164 confess "Could not generate inline reader because : $e" if $e;
165
166 return $code;
167}
168
169sub _generate_writer_method_inline {
170 my $self = shift;
171 my $attr = $self->associated_attribute;
172 my $attr_name = $attr->name;
173 my $meta_instance = $attr->associated_class->instance_metaclass;
174
175 my ( $code, $e ) = $self->_eval_closure(
176 {},
177 'sub {'
178 . $meta_instance->inline_set_slot_value('$_[0]', $attr_name, '$_[1]')
179 . '}'
180 );
181 confess "Could not generate inline writer because : $e" if $e;
182
183 return $code;
184}
185
186sub _generate_predicate_method_inline {
187 my $self = shift;
188 my $attr = $self->associated_attribute;
189 my $attr_name = $attr->name;
190 my $meta_instance = $attr->associated_class->instance_metaclass;
191
192 my ( $code, $e ) = $self->_eval_closure(
193 {},
194 'sub {'
195 . $meta_instance->inline_is_slot_initialized('$_[0]', $attr_name)
196 . '}'
197 );
198 confess "Could not generate inline predicate because : $e" if $e;
199
200 return $code;
201}
202
203sub _generate_clearer_method_inline {
204 my $self = shift;
205 my $attr = $self->associated_attribute;
206 my $attr_name = $attr->name;
207 my $meta_instance = $attr->associated_class->instance_metaclass;
208
209 my ( $code, $e ) = $self->_eval_closure(
210 {},
211 'sub {'
212 . $meta_instance->inline_deinitialize_slot('$_[0]', $attr_name)
213 . '}'
214 );
215 confess "Could not generate inline clearer because : $e" if $e;
216
217 return $code;
218}
219
2201;
221
222__END__
223
224=pod
225
226=head1 NAME
227
228Class::MOP::Method::Accessor - Method Meta Object for accessors
229
230=head1 SYNOPSIS
231
232 use Class::MOP::Method::Accessor;
233
234 my $reader = Class::MOP::Method::Accessor->new(
235 attribute => $attribute,
236 is_inline => 1,
237 accessor_type => 'reader',
238 );
239
240 $reader->body->execute($instance); # call the reader method
241
242=head1 DESCRIPTION
243
244This is a subclass of <Class::MOP::Method> which is used by
245C<Class::MOP::Attribute> to generate accessor code. It handles
246generation of readers, writers, predicates and clearers. For each type
247of method, it can either create a subroutine reference, or actually
248inline code by generating a string and C<eval>'ing it.
249
250=head1 METHODS
251
252=over 4
253
254=item B<< Class::MOP::Method::Accessor->new(%options) >>
255
256This returns a new C<Class::MOP::Method::Accessor> based on the
257C<%options> provided.
258
259=over 4
260
261=item * attribute
262
263This is the C<Class::MOP::Attribute> for which accessors are being
264generated. This option is required.
265
266=item * accessor_type
267
268This is a string which should be one of "reader", "writer",
269"accessor", "predicate", or "clearer". This is the type of method
270being generated. This option is required.
271
272=item * is_inline
273
274This indicates whether or not the accessor should be inlined. This
275defaults to false.
276
277=item * name
278
279The method name (without a package name). This is required.
280
281=item * package_name
282
283The package name for the method. This is required.
284
285=back
286
287=item B<< $metamethod->accessor_type >>
288
289Returns the accessor type which was passed to C<new>.
290
291=item B<< $metamethod->is_inline >>
292
293Returns a boolean indicating whether or not the accessor is inlined.
294
295=item B<< $metamethod->associated_attribute >>
296
297This returns the L<Class::MOP::Attribute> object which was passed to
298C<new>.
299
300=item B<< $metamethod->body >>
301
302The method itself is I<generated> when the accessor object is
303constructed.
304
305=back
306
307=head1 AUTHORS
308
309Stevan Little E<lt>stevan@iinteractive.comE<gt>
310
311=head1 COPYRIGHT AND LICENSE
312
313Copyright 2006-2009 by Infinity Interactive, Inc.
314
315L<http://www.iinteractive.com>
316
317This library is free software; you can redistribute it and/or modify
318it under the same terms as Perl itself.
319
320=cut
321