2 package Class::MOP::Method::Accessor;
8 use Scalar::Util 'blessed', 'weaken';
11 use base 'Class::MOP::Method::Generated';
17 (exists $options{attribute})
18 || confess "You must supply an attribute to construct with";
20 (exists $options{accessor_type})
21 || confess "You must supply an accessor_type to construct with";
23 (blessed($options{attribute}) && $options{attribute}->isa('Class::MOP::Attribute'))
24 || confess "You must supply an attribute which is a 'Class::MOP::Attribute' instance";
26 ($options{package_name} && $options{name})
27 || confess "You must supply the package_name and name parameters $Class::MOP::Method::UPGRADE_ERROR_TEXT";
29 my $self = $class->_new(\%options);
31 # we don't want this creating
32 # a cycle in the code, if not
34 weaken($self->{'attribute'});
36 $self->_initialize_body;
44 return Class::MOP::Class->initialize($class)->new_object(@_)
45 if $class ne __PACKAGE__;
47 my $params = @_ == 1 ? $_[0] : {@_};
50 # inherited from Class::MOP::Method
51 body => $params->{body},
52 associated_metaclass => $params->{associated_metaclass},
53 package_name => $params->{package_name},
54 name => $params->{name},
55 original_method => $params->{original_method},
57 # inherit from Class::MOP::Generated
58 is_inline => $params->{is_inline} || 0,
59 definition_context => $params->{definition_context},
61 # defined in this class
62 attribute => $params->{attribute},
63 accessor_type => $params->{accessor_type},
69 sub associated_attribute { (shift)->{'attribute'} }
70 sub accessor_type { (shift)->{'accessor_type'} }
74 sub _initialize_body {
77 my $method_name = join "_" => (
81 ($self->is_inline ? 'inline' : ())
84 $self->{'body'} = $self->$method_name();
89 sub _generate_accessor_method {
91 my $attr = $self->associated_attribute;
95 $attr->set_value($_[0], $_[1]);
97 $attr->get_value($_[0]);
101 sub _generate_accessor_method_inline {
103 my $attr = $self->associated_attribute;
106 $self->_compile_code([
109 $attr->_inline_set_value('$_[0]', '$_[1]'),
111 $attr->_inline_get_value('$_[0]'),
116 confess "Could not generate inline accessor because : $_";
120 sub _generate_reader_method {
122 my $attr = $self->associated_attribute;
125 confess "Cannot assign a value to a read-only accessor"
127 $attr->get_value($_[0]);
131 sub _generate_reader_method_inline {
133 my $attr = $self->associated_attribute;
136 $self->_compile_code([
139 # XXX: this is a hack, but our error stuff is terrible
140 $self->_inline_throw_error(
141 '"Cannot assign a value to a read-only accessor"',
145 $attr->_inline_get_value('$_[0]'),
150 confess "Could not generate inline reader because : $_";
154 sub _inline_throw_error {
156 return 'confess ' . $_[0];
159 sub _generate_writer_method {
161 my $attr = $self->associated_attribute;
164 $attr->set_value($_[0], $_[1]);
168 sub _generate_writer_method_inline {
170 my $attr = $self->associated_attribute;
173 $self->_compile_code([
175 $attr->_inline_set_value('$_[0]', '$_[1]'),
180 confess "Could not generate inline writer because : $_";
184 sub _generate_predicate_method {
186 my $attr = $self->associated_attribute;
189 $attr->has_value($_[0])
193 sub _generate_predicate_method_inline {
195 my $attr = $self->associated_attribute;
198 $self->_compile_code([
200 $attr->_inline_has_value('$_[0]'),
205 confess "Could not generate inline predicate because : $_";
209 sub _generate_clearer_method {
211 my $attr = $self->associated_attribute;
214 $attr->clear_value($_[0])
218 sub _generate_clearer_method_inline {
220 my $attr = $self->associated_attribute;
223 $self->_compile_code([
225 $attr->_inline_clear_value('$_[0]'),
230 confess "Could not generate inline clearer because : $_";
236 # ABSTRACT: Method Meta Object for accessors
244 use Class::MOP::Method::Accessor;
246 my $reader = Class::MOP::Method::Accessor->new(
247 attribute => $attribute,
249 accessor_type => 'reader',
252 $reader->body->execute($instance); # call the reader method
256 This is a subclass of C<Class::MOP::Method> which is used by
257 C<Class::MOP::Attribute> to generate accessor code. It handles
258 generation of readers, writers, predicates and clearers. For each type
259 of method, it can either create a subroutine reference, or actually
260 inline code by generating a string and C<eval>'ing it.
266 =item B<< Class::MOP::Method::Accessor->new(%options) >>
268 This returns a new C<Class::MOP::Method::Accessor> based on the
269 C<%options> provided.
275 This is the C<Class::MOP::Attribute> for which accessors are being
276 generated. This option is required.
278 =item * accessor_type
280 This is a string which should be one of "reader", "writer",
281 "accessor", "predicate", or "clearer". This is the type of method
282 being generated. This option is required.
286 This indicates whether or not the accessor should be inlined. This
291 The method name (without a package name). This is required.
295 The package name for the method. This is required.
299 =item B<< $metamethod->accessor_type >>
301 Returns the accessor type which was passed to C<new>.
303 =item B<< $metamethod->is_inline >>
305 Returns a boolean indicating whether or not the accessor is inlined.
307 =item B<< $metamethod->associated_attribute >>
309 This returns the L<Class::MOP::Attribute> object which was passed to
312 =item B<< $metamethod->body >>
314 The method itself is I<generated> when the accessor object is