Add initial split out Reader accessor method
[gitmo/Class-MOP.git] / lib / Class / MOP / Attribute.pm
CommitLineData
8b978dd5 1
2package Class::MOP::Attribute;
3
4use strict;
5use warnings;
6
ba38bf08 7use Class::MOP::Method::Accessor;
32b01180 8use Class::MOP::Method::Reader;
9use Class::MOP::Method::Writer;
ba38bf08 10
2eb717d5 11use Carp 'confess';
9b522fc4 12use Scalar::Util 'blessed', 'weaken';
2eb717d5 13
f6ca0704 14our $VERSION = '0.94';
d519662a 15$VERSION = eval $VERSION;
f0480c45 16our $AUTHORITY = 'cpan:STEVAN';
8b978dd5 17
b1897d4d 18use base 'Class::MOP::Object';
19
727919c5 20# NOTE: (meta-circularity)
1d68af04 21# This method will be replaced in the
22# boostrap section of Class::MOP, by
23# a new version which uses the
727919c5 24# &Class::MOP::Class::construct_instance
25# method to build an attribute meta-object
26# which itself is described with attribute
1d68af04 27# meta-objects.
727919c5 28# - Ain't meta-circularity grand? :)
8b978dd5 29sub new {
649efb63 30 my ( $class, @args ) = @_;
31
32 unshift @args, "name" if @args % 2 == 1;
33 my %options = @args;
34
35 my $name = $options{name};
1d68af04 36
d9330488 37 (defined $name)
8b978dd5 38 || confess "You must provide a name for the attribute";
1d68af04 39
40 $options{init_arg} = $name
5659d76e 41 if not exists $options{init_arg};
1d68af04 42 if(exists $options{builder}){
43 confess("builder must be a defined scalar value which is a method name")
44 if ref $options{builder} || !(defined $options{builder});
45 confess("Setting both default and builder is not allowed.")
46 if exists $options{default};
8fe581e5 47 } else {
48 (is_default_a_coderef(\%options))
49 || confess("References are not allowed as default values, you must ".
3c0a8087 50 "wrap the default of '$name' in a CODE reference (ex: sub { [] } and not [])")
8fe581e5 51 if exists $options{default} && ref $options{default};
1d68af04 52 }
2e877f58 53 if( $options{required} and not( defined($options{builder}) || defined($options{init_arg}) || exists $options{default} ) ) {
54 confess("A required attribute must have either 'init_arg', 'builder', or 'default'");
55 }
8683db0e 56
cb75020f 57 $class->_new(\%options);
4b698b1a 58}
59
60sub _new {
0bfc85b8 61 my $class = shift;
ec9e38e5 62
63 return Class::MOP::Class->initialize($class)->new_object(@_)
812d58f9 64 if $class ne __PACKAGE__;
ec9e38e5 65
0bfc85b8 66 my $options = @_ == 1 ? $_[0] : {@_};
4b698b1a 67
8b978dd5 68 bless {
d9d99689 69 'name' => $options->{name},
70 'accessor' => $options->{accessor},
71 'reader' => $options->{reader},
72 'writer' => $options->{writer},
73 'predicate' => $options->{predicate},
74 'clearer' => $options->{clearer},
75 'builder' => $options->{builder},
76 'init_arg' => $options->{init_arg},
77 'default' => $options->{default},
78 'initializer' => $options->{initializer},
79 'definition_context' => $options->{definition_context},
06a88dbb 80 'lazy' => $options->{lazy},
1d68af04 81 # keep a weakened link to the
9ec169fe 82 # class we are associated with
8683db0e 83 'associated_class' => undef,
1d68af04 84 # and a list of the methods
3545c727 85 # associated with this attr
8683db0e 86 'associated_methods' => [],
dc9d420c 87 # this let's us keep track of
88 # our order inside the associated
89 # class
90 'insertion_order' => undef,
0bfc85b8 91 }, $class;
8b978dd5 92}
93
7b31baf4 94# NOTE:
1d68af04 95# this is a primative (and kludgy) clone operation
16e960bd 96# for now, it will be replaced in the Class::MOP
1d68af04 97# bootstrap with a proper one, however we know
5659d76e 98# that this one will work fine for now.
99sub clone {
100 my $self = shift;
101 my %options = @_;
102 (blessed($self))
103 || confess "Can only clone an instance";
b3fa93c7 104 return bless { %{$self}, %options } => ref($self);
5659d76e 105}
106
06a88dbb 107sub _call_builder {
108 my ( $self, $instance ) = @_;
109
110 my $builder = $self->builder();
111
112 return $instance->$builder()
113 if $instance->can( $self->builder );
114
115 $self->throw_error( blessed($instance)
116 . " does not support builder method '"
117 . $self->builder
118 . "' for attribute '"
119 . $self->name
120 . "'",
121 object => $instance,
122 );
123}
124
bd4e03f9 125sub initialize_instance_slot {
f892c0f0 126 my ($self, $meta_instance, $instance, $params) = @_;
8683db0e 127 my $init_arg = $self->{'init_arg'};
128
06a88dbb 129 my ($val, $value_is_set);
bd4e03f9 130 # try to fetch the init arg from the %params ...
8d2d4c67 131
1d68af04 132 # if nothing was in the %params, we can use the
bd4e03f9 133 # attribute's default value (if it has one)
2e877f58 134 if(defined $init_arg and exists $params->{$init_arg}){
06a88dbb 135 $val = $params->{$init_arg};
136 $value_is_set = 1;
137 } else {
138 return if $self->is_lazy;
139
140 if($self->has_default){
141 $val = $self->default($instance);
142 $value_is_set = 1;
143 } elsif($self->has_builder){
144 $val = $self->_call_builder($instance);
145 $value_is_set = 1;
8fe581e5 146 }
1d68af04 147 }
06a88dbb 148
149 return unless $value_is_set;
150
151 $self->_set_initial_slot_value(
152 $meta_instance,
153 $instance,
154 $val,
155 );
156
bd4e03f9 157}
158
8ee74136 159sub _set_initial_slot_value {
160 my ($self, $meta_instance, $instance, $value) = @_;
161
162 my $slot_name = $self->name;
163
164 return $meta_instance->set_slot_value($instance, $slot_name, $value)
165 unless $self->has_initializer;
166
167 my $callback = sub {
168 $meta_instance->set_slot_value($instance, $slot_name, $_[0]);
169 };
170
171 my $initializer = $self->initializer;
172
173 # most things will just want to set a value, so make it first arg
174 $instance->$initializer($value, $callback, $self);
175}
176
5659d76e 177# NOTE:
1d68af04 178# the next bunch of methods will get bootstrapped
7b31baf4 179# away in the Class::MOP bootstrapping section
180
8683db0e 181sub associated_class { $_[0]->{'associated_class'} }
182sub associated_methods { $_[0]->{'associated_methods'} }
183
b3fa93c7 184sub has_accessor { defined($_[0]->{'accessor'}) }
185sub has_reader { defined($_[0]->{'reader'}) }
186sub has_writer { defined($_[0]->{'writer'}) }
187sub has_predicate { defined($_[0]->{'predicate'}) }
188sub has_clearer { defined($_[0]->{'clearer'}) }
189sub has_builder { defined($_[0]->{'builder'}) }
190sub has_init_arg { defined($_[0]->{'init_arg'}) }
191sub has_default { defined($_[0]->{'default'}) }
192sub has_initializer { defined($_[0]->{'initializer'}) }
dc9d420c 193sub has_insertion_order { defined($_[0]->{'insertion_order'}) }
8683db0e 194
d9d99689 195sub accessor { $_[0]->{'accessor'} }
196sub reader { $_[0]->{'reader'} }
197sub writer { $_[0]->{'writer'} }
198sub predicate { $_[0]->{'predicate'} }
199sub clearer { $_[0]->{'clearer'} }
200sub builder { $_[0]->{'builder'} }
201sub init_arg { $_[0]->{'init_arg'} }
202sub initializer { $_[0]->{'initializer'} }
203sub definition_context { $_[0]->{'definition_context'} }
dc9d420c 204sub insertion_order { $_[0]->{'insertion_order'} }
943cbe2d 205sub _set_insertion_order { $_[0]->{'insertion_order'} = $_[1] }
06a88dbb 206sub is_lazy { $_[0]->{'lazy'} }
c50c603e 207
7b31baf4 208# end bootstrapped away method section.
209# (all methods below here are kept intact)
210
9e517e01 211sub has_read_method { $_[0]->has_reader || $_[0]->has_accessor }
212sub has_write_method { $_[0]->has_writer || $_[0]->has_accessor }
213
d14f6cbe 214sub get_read_method {
215 my $self = shift;
216 my $reader = $self->reader || $self->accessor;
217 # normal case ...
218 return $reader unless ref $reader;
219 # the HASH ref case
220 my ($name) = %$reader;
221 return $name;
222}
223
224sub get_write_method {
225 my $self = shift;
226 my $writer = $self->writer || $self->accessor;
227 # normal case ...
228 return $writer unless ref $writer;
229 # the HASH ref case
230 my ($name) = %$writer;
231 return $name;
232}
b25109b1 233
5da16d1b 234sub get_read_method_ref {
235 my $self = shift;
742fb371 236 if ((my $reader = $self->get_read_method) && $self->associated_class) {
5da16d1b 237 return $self->associated_class->get_method($reader);
238 }
239 else {
def5c0b5 240 my $code = sub { $self->get_value(@_) };
241 if (my $class = $self->associated_class) {
242 return $class->method_metaclass->wrap(
243 $code,
244 package_name => $class->name,
245 name => '__ANON__'
246 );
247 }
248 else {
249 return $code;
250 }
5da16d1b 251 }
252}
253
254sub get_write_method_ref {
255 my $self = shift;
d14f6cbe 256 if ((my $writer = $self->get_write_method) && $self->associated_class) {
742fb371 257 return $self->associated_class->get_method($writer);
5da16d1b 258 }
259 else {
def5c0b5 260 my $code = sub { $self->set_value(@_) };
261 if (my $class = $self->associated_class) {
262 return $class->method_metaclass->wrap(
263 $code,
264 package_name => $class->name,
265 name => '__ANON__'
266 );
267 }
268 else {
269 return $code;
270 }
5da16d1b 271 }
272}
273
1d68af04 274sub is_default_a_coderef {
ed337aad 275 my ($value) = $_[0]->{'default'};
276 return unless ref($value);
277 return ref($value) eq 'CODE' || (blessed($value) && $value->isa('Class::MOP::Method'));
c0cbf4d9 278}
279
1d68af04 280sub default {
c0cbf4d9 281 my ($self, $instance) = @_;
9363ea89 282 if (defined $instance && $self->is_default_a_coderef) {
1d68af04 283 # if the default is a CODE ref, then
727919c5 284 # we pass in the instance and default
1d68af04 285 # can return a value based on that
727919c5 286 # instance. Somewhat crude, but works.
8683db0e 287 return $self->{'default'}->($instance);
1d68af04 288 }
8683db0e 289 $self->{'default'};
c50c603e 290}
8b978dd5 291
c57c8b10 292# slots
293
294sub slots { (shift)->name }
295
1d68af04 296# class association
727919c5 297
9ec169fe 298sub attach_to_class {
299 my ($self, $class) = @_;
300 (blessed($class) && $class->isa('Class::MOP::Class'))
301 || confess "You must pass a Class::MOP::Class instance (or a subclass)";
8683db0e 302 weaken($self->{'associated_class'} = $class);
9ec169fe 303}
304
305sub detach_from_class {
306 my $self = shift;
8683db0e 307 $self->{'associated_class'} = undef;
9ec169fe 308}
309
1d68af04 310# method association
3545c727 311
312sub associate_method {
313 my ($self, $method) = @_;
8683db0e 314 push @{$self->{'associated_methods'}} => $method;
3545c727 315}
316
16e960bd 317## Slot management
318
ef91a0e2 319sub set_initial_value {
320 my ($self, $instance, $value) = @_;
e76b01fb 321 $self->_set_initial_slot_value(
b3fa93c7 322 Class::MOP::Class->initialize(ref($instance))->get_meta_instance,
8ee74136 323 $instance,
324 $value
325 );
ef91a0e2 326}
327
7e5efe15 328sub set_value { shift->set_raw_value(@_) }
329sub get_value { shift->get_raw_value(@_) }
330
331sub set_raw_value {
1396f86b 332 my ($self, $instance, $value) = @_;
16e960bd 333
b3fa93c7 334 Class::MOP::Class->initialize(ref($instance))
da34f054 335 ->get_meta_instance
336 ->set_slot_value($instance, $self->name, $value);
16e960bd 337}
338
7e5efe15 339sub get_raw_value {
1396f86b 340 my ($self, $instance) = @_;
16e960bd 341
06a88dbb 342 if($self->is_lazy && !$self->has_value($instance)){
343 my $val;
344
345 if($self->has_default){
346 $val = $self->default($instance);
347 } elsif($self->has_builder){
348 $val = $self->_call_builder($instance);
349 }
350
351 $self->set_initial_value(
352 $instance,
353 $val,
354 );
355 }
356
b3fa93c7 357 Class::MOP::Class->initialize(ref($instance))
da34f054 358 ->get_meta_instance
359 ->get_slot_value($instance, $self->name);
16e960bd 360}
361
3545c727 362sub has_value {
363 my ($self, $instance) = @_;
1d68af04 364
b3fa93c7 365 Class::MOP::Class->initialize(ref($instance))
da34f054 366 ->get_meta_instance
367 ->is_slot_initialized($instance, $self->name);
3545c727 368}
369
370sub clear_value {
371 my ($self, $instance) = @_;
1d68af04 372
b3fa93c7 373 Class::MOP::Class->initialize(ref($instance))
da34f054 374 ->get_meta_instance
375 ->deinitialize_slot($instance, $self->name);
3545c727 376}
377
ba38bf08 378## load em up ...
c0cbf4d9 379
ba38bf08 380sub accessor_metaclass { 'Class::MOP::Method::Accessor' }
32b01180 381sub method_metaclasses {
382 {
383 reader => 'Class::MOP::Method::Reader',
384 #writer => 'Class::MOP::Method::Writer',
385 }
386}
c0cbf4d9 387
45a183fb 388sub _process_accessors {
c0cbf4d9 389 my ($self, $type, $accessor, $generate_as_inline_methods) = @_;
d9d99689 390
391 my $method_ctx;
392
393 if ( my $ctx = $self->definition_context ) {
394 $method_ctx = { %$ctx };
395 }
396
9b522fc4 397 if (ref($accessor)) {
398 (ref($accessor) eq 'HASH')
7d28758b 399 || confess "bad accessor/reader/writer/predicate/clearer format, must be a HASH ref";
4d47b77f 400 my ($name, $method) = %{$accessor};
4c105333 401 $method = $self->accessor_metaclass->wrap(
402 $method,
403 package_name => $self->associated_class->name,
404 name => $name,
d9d99689 405 definition_context => $method_ctx,
4c105333 406 );
3545c727 407 $self->associate_method($method);
1d68af04 408 return ($name, $method);
2eb717d5 409 }
9ec169fe 410 else {
1d68af04 411 my $inline_me = ($generate_as_inline_methods && $self->associated_class->instance_metaclass->is_inlinable);
ba38bf08 412 my $method;
413 eval {
d9d99689 414 if ( $method_ctx ) {
415 my $desc = "accessor $accessor";
416 if ( $accessor ne $self->name ) {
417 $desc .= " of attribute " . $self->name;
418 }
419
420 $method_ctx->{description} = $desc;
421 }
422
32b01180 423 my $method_metaclass = $self->method_metaclasses->{$type} || $self->accessor_metaclass;
424
425 $method = $method_metaclass->new(
ba38bf08 426 attribute => $self,
d90b42a6 427 is_inline => $inline_me,
ba38bf08 428 accessor_type => $type,
4c105333 429 package_name => $self->associated_class->name,
430 name => $accessor,
d9d99689 431 definition_context => $method_ctx,
1d68af04 432 );
ba38bf08 433 };
1d68af04 434 confess "Could not create the '$type' method for " . $self->name . " because : $@" if $@;
3545c727 435 $self->associate_method($method);
ba38bf08 436 return ($accessor, $method);
1d68af04 437 }
9ec169fe 438}
439
440sub install_accessors {
c0cbf4d9 441 my $self = shift;
442 my $inline = shift;
443 my $class = $self->associated_class;
1d68af04 444
9ec169fe 445 $class->add_method(
45a183fb 446 $self->_process_accessors('accessor' => $self->accessor(), $inline)
9ec169fe 447 ) if $self->has_accessor();
448
1d68af04 449 $class->add_method(
45a183fb 450 $self->_process_accessors('reader' => $self->reader(), $inline)
9ec169fe 451 ) if $self->has_reader();
452
453 $class->add_method(
45a183fb 454 $self->_process_accessors('writer' => $self->writer(), $inline)
9ec169fe 455 ) if $self->has_writer();
456
457 $class->add_method(
45a183fb 458 $self->_process_accessors('predicate' => $self->predicate(), $inline)
9ec169fe 459 ) if $self->has_predicate();
1d68af04 460
7d28758b 461 $class->add_method(
45a183fb 462 $self->_process_accessors('clearer' => $self->clearer(), $inline)
7d28758b 463 ) if $self->has_clearer();
1d68af04 464
9ec169fe 465 return;
2eb717d5 466}
467
b51af7f9 468{
469 my $_remove_accessor = sub {
470 my ($accessor, $class) = @_;
9b522fc4 471 if (ref($accessor) && ref($accessor) eq 'HASH') {
c50c603e 472 ($accessor) = keys %{$accessor};
1d68af04 473 }
474 my $method = $class->get_method($accessor);
475 $class->remove_method($accessor)
32b01180 476 if (ref($method) && $method->isa('Class::MOP::Method::Attribute'));
b51af7f9 477 };
1d68af04 478
b51af7f9 479 sub remove_accessors {
9ec169fe 480 my $self = shift;
2367814a 481 # TODO:
1d68af04 482 # we really need to make sure to remove from the
483 # associates methods here as well. But this is
484 # such a slimly used method, I am not worried
2367814a 485 # about it right now.
9ec169fe 486 $_remove_accessor->($self->accessor(), $self->associated_class()) if $self->has_accessor();
487 $_remove_accessor->($self->reader(), $self->associated_class()) if $self->has_reader();
488 $_remove_accessor->($self->writer(), $self->associated_class()) if $self->has_writer();
489 $_remove_accessor->($self->predicate(), $self->associated_class()) if $self->has_predicate();
7d28758b 490 $_remove_accessor->($self->clearer(), $self->associated_class()) if $self->has_clearer();
1d68af04 491 return;
b51af7f9 492 }
493
8b978dd5 494}
495
4961;
497
498__END__
499
500=pod
501
1d68af04 502=head1 NAME
8b978dd5 503
504Class::MOP::Attribute - Attribute Meta Object
505
506=head1 SYNOPSIS
1d68af04 507
2e23f7dc 508 Class::MOP::Attribute->new(
509 foo => (
510 accessor => 'foo', # dual purpose get/set accessor
511 predicate => 'has_foo', # predicate check for defined-ness
512 init_arg => '-foo', # class->new will look for a -foo key
513 default => 'BAR IS BAZ!' # if no -foo key is provided, use this
514 )
515 );
516
517 Class::MOP::Attribute->new(
518 bar => (
519 reader => 'bar', # getter
520 writer => 'set_bar', # setter
521 predicate => 'has_bar', # predicate check for defined-ness
522 init_arg => ':bar', # class->new will look for a :bar key
523 # no default value means it is undef
524 )
525 );
8b978dd5 526
527=head1 DESCRIPTION
528
2e23f7dc 529The Attribute Protocol is almost entirely an invention of
530C<Class::MOP>. Perl 5 does not have a consistent notion of
531attributes. There are so many ways in which this is done, and very few
532(if any) are easily discoverable by this module.
552e3d24 533
2e23f7dc 534With that said, this module attempts to inject some order into this
1d68af04 535chaos, by introducing a consistent API which can be used to create
fe122940 536object attributes.
552e3d24 537
538=head1 METHODS
539
540=head2 Creation
541
542=over 4
543
2e23f7dc 544=item B<< Class::MOP::Attribute->new($name, ?%options) >>
fe122940 545
1d68af04 546An attribute must (at the very least), have a C<$name>. All other
2e23f7dc 547C<%options> are added as key-value pairs.
fe122940 548
2e23f7dc 549=over 8
fe122940 550
76187047 551=item * init_arg
fe122940 552
2e23f7dc 553This is a string value representing the expected key in an
554initialization hash. For instance, if we have an C<init_arg> value of
555C<-foo>, then the following code will Just Work.
fe122940 556
d69fb6b3 557 MyClass->meta->new_object( -foo => 'Hello There' );
fe122940 558
2e23f7dc 559If an init_arg is not assigned, it will automatically use the
560attribute's name. If C<init_arg> is explicitly set to C<undef>, the
561attribute cannot be specified during initialization.
7b31baf4 562
76187047 563=item * builder
1d68af04 564
2e23f7dc 565This provides the name of a method that will be called to initialize
566the attribute. This method will be called on the object after it is
567constructed. It is expected to return a valid value for the attribute.
fe122940 568
76187047 569=item * default
4c4a6c41 570
2e23f7dc 571This can be used to provide an explicit default for initializing the
572attribute. If the default you provide is a subroutine reference, then
573this reference will be called I<as a method> on the object.
4c4a6c41 574
2e23f7dc 575If the value is a simple scalar (string or number), then it can be
576just passed as is. However, if you wish to initialize it with a HASH
577or ARRAY ref, then you need to wrap that inside a subroutine
578reference:
fe122940 579
2e23f7dc 580 Class::MOP::Attribute->new(
581 'foo' => (
582 default => sub { [] },
583 )
584 );
1d68af04 585
586 # or ...
587
2e23f7dc 588 Class::MOP::Attribute->new(
589 'foo' => (
590 default => sub { {} },
591 )
592 );
593
594If you wish to initialize an attribute with a subroutine reference
595itself, then you need to wrap that in a subroutine as well:
596
597 Class::MOP::Attribute->new(
598 'foo' => (
599 default => sub {
600 sub { print "Hello World" }
601 },
602 )
603 );
604
605And lastly, if the value of your attribute is dependent upon some
606other aspect of the instance structure, then you can take advantage of
607the fact that when the C<default> value is called as a method:
608
609 Class::MOP::Attribute->new(
610 'object_identity' => (
611 default => sub { Scalar::Util::refaddr( $_[0] ) },
612 )
613 );
614
615Note that there is no guarantee that attributes are initialized in any
616particular order, so you cannot rely on the value of some other
617attribute when generating the default.
fe122940 618
76187047 619=item * initializer
0ef07b33 620
2e23f7dc 621This option can be either a method name or a subroutine
622reference. This method will be called when setting the attribute's
623value in the constructor. Unlike C<default> and C<builder>, the
624initializer is only called when a value is provided to the
625constructor. The initializer allows you to munge this value during
626object construction.
627
628The initializer is called as a method with three arguments. The first
629is the value that was passed to the constructor. The second is a
630subroutine reference that can be called to actually set the
631attribute's value, and the last is the associated
632C<Class::MOP::Attribute> object.
633
634This contrived example shows an initializer that sets the attribute to
635twice the given value.
636
637 Class::MOP::Attribute->new(
638 'doubled' => (
639 initializer => sub {
ea62c8ab 640 my ( $self, $value, $set, $attr ) = @_;
2e23f7dc 641 $set->( $value * 2 );
642 },
643 )
644 );
645
646Since an initializer can be a method name, you can easily make
0ef07b33 647attribute initialization use the writer:
648
2e23f7dc 649 Class::MOP::Attribute->new(
650 'some_attr' => (
651 writer => 'some_attr',
652 initializer => 'some_attr',
653 )
654 );
0ef07b33 655
2e23f7dc 656Your writer will need to examine C<@_> and determine under which
657context it is being called.
127d39a7 658
fe122940 659=back
660
2e23f7dc 661The C<accessor>, C<reader>, C<writer>, C<predicate> and C<clearer>
662options all accept the same parameters. You can provide the name of
663the method, in which case an appropriate default method will be
664generated for you. Or instead you can also provide hash reference
665containing exactly one key (the method name) and one value. The value
666should be a subroutine reference, which will be installed as the
667method itself.
59e7697f 668
76187047 669=over 8
59e7697f 670
76187047 671=item * accessor
59e7697f 672
2e23f7dc 673An C<accessor> is a standard Perl-style read/write accessor. It will
674return the value of the attribute, and if a value is passed as an
675argument, it will assign that value to the attribute.
fe122940 676
2e23f7dc 677Note that C<undef> is a legitimate value, so this will work:
fe122940 678
679 $object->set_something(undef);
680
76187047 681=item * reader
59e7697f 682
2e23f7dc 683This is a basic read-only accessor. It returns the value of the
684attribute.
fe122940 685
76187047 686=item * writer
59e7697f 687
1d68af04 688This is a basic write accessor, it accepts a single argument, and
2e23f7dc 689assigns that value to the attribute.
59e7697f 690
2e23f7dc 691Note that C<undef> is a legitimate value, so this will work:
59e7697f 692
2e23f7dc 693 $object->set_something(undef);
fe122940 694
76187047 695=item * predicate
fe122940 696
2e23f7dc 697The predicate method returns a boolean indicating whether or not the
698attribute has been explicitly set.
07dca7e3 699
2e23f7dc 700Note that the predicate returns true even if the attribute was set to
701a false value (C<0> or C<undef>).
07dca7e3 702
76187047 703=item * clearer
7d28758b 704
2e23f7dc 705This method will uninitialize the attribute. After an attribute is
706cleared, its C<predicate> will return false.
7d28758b 707
76187047 708=item * definition_context
f8813817 709
710Mostly, this exists as a hook for the benefit of Moose.
711
712This option should be a hash reference containing several keys which
713will be used when inlining the attribute's accessors. The keys should
714include C<line>, the line number where the attribute was created, and
715either C<file> or C<description>.
716
717This information will ultimately be used when eval'ing inlined
718accessor code so that error messages report a useful line and file
719name.
720
59e7697f 721=back
552e3d24 722
2e23f7dc 723=item B<< $attr->clone(%options) >>
bd4e03f9 724
2e23f7dc 725This clones the attribute. Any options you provide will override the
726settings of the original attribute. You can change the name of the new
727attribute by passing a C<name> key in C<%options>.
127d39a7 728
2e23f7dc 729=back
bd4e03f9 730
2e23f7dc 731=head2 Informational
127d39a7 732
2e23f7dc 733These are all basic read-only accessors for the values passed into
734the constructor.
552e3d24 735
2e23f7dc 736=over 4
16e960bd 737
2e23f7dc 738=item B<< $attr->name >>
2367814a 739
76187047 740Returns the attribute's name.
741
2e23f7dc 742=item B<< $attr->accessor >>
2367814a 743
2e23f7dc 744=item B<< $attr->reader >>
16e960bd 745
2e23f7dc 746=item B<< $attr->writer >>
16e960bd 747
2e23f7dc 748=item B<< $attr->predicate >>
16e960bd 749
2e23f7dc 750=item B<< $attr->clearer >>
c0921932 751
2e23f7dc 752The C<accessor>, C<reader>, C<writer>, C<predicate>, and C<clearer>
753methods all return exactly what was passed to the constructor, so it
a6710c60 754can be either a string containing a method name, or a hash reference.
c0921932 755
2e23f7dc 756=item B<< $attr->initializer >>
16e960bd 757
a6710c60 758Returns the initializer as passed to the constructor, so this may be
2e23f7dc 759either a method name or a subroutine reference.
16e960bd 760
2e23f7dc 761=item B<< $attr->init_arg >>
3545c727 762
2e23f7dc 763=item B<< $attr->is_default_a_coderef >>
2367814a 764
2e23f7dc 765=item B<< $attr->default($instance) >>
3545c727 766
2e23f7dc 767The C<$instance> argument is optional. If you don't pass it, the
768return value for this method is exactly what was passed to the
769constructor, either a simple scalar or a subroutine reference.
2367814a 770
2e23f7dc 771If you I<do> pass an C<$instance> and the default is a subroutine
772reference, then the reference is called as a method on the
773C<$instance> and the generated value is returned.
16e960bd 774
2e23f7dc 775=item B<< $attr->slots >>
552e3d24 776
2e23f7dc 777Return a list of slots required by the attribute. This is usually just
778one, the name of the attribute.
fe122940 779
2e23f7dc 780A slot is the name of the hash key used to store the attribute in an
781object instance.
552e3d24 782
2e23f7dc 783=item B<< $attr->get_read_method >>
552e3d24 784
2e23f7dc 785=item B<< $attr->get_write_method >>
552e3d24 786
2e23f7dc 787Returns the name of a method suitable for reading or writing the value
788of the attribute in the associated class.
552e3d24 789
2e23f7dc 790If an attribute is read- or write-only, then these methods can return
791C<undef> as appropriate.
552e3d24 792
2e23f7dc 793=item B<< $attr->has_read_method >>
c50c603e 794
2e23f7dc 795=item B<< $attr->has_write_method >>
7d28758b 796
2e23f7dc 797This returns a boolean indicating whether the attribute has a I<named>
798read or write method.
0ab65f99 799
2e23f7dc 800=item B<< $attr->get_read_method_ref >>
552e3d24 801
2e23f7dc 802=item B<< $attr->get_write_method_ref >>
495af518 803
2e23f7dc 804Returns the subroutine reference of a method suitable for reading or
805writing the attribute's value in the associated class. These methods
806always return a subroutine reference, regardless of whether or not the
807attribute is read- or write-only.
808
eeff7496 809=item B<< $attr->insertion_order >>
810
811If this attribute has been inserted into a class, this returns a zero
812based index regarding the order of insertion.
813
2e23f7dc 814=back
fe122940 815
2e23f7dc 816=head2 Informational predicates
92d2abfa 817
2e23f7dc 818These are all basic predicate methods for the values passed into C<new>.
552e3d24 819
2e23f7dc 820=over 4
c57c8b10 821
2e23f7dc 822=item B<< $attr->has_accessor >>
c57c8b10 823
2e23f7dc 824=item B<< $attr->has_reader >>
b25109b1 825
2e23f7dc 826=item B<< $attr->has_writer >>
b25109b1 827
2e23f7dc 828=item B<< $attr->has_predicate >>
5da16d1b 829
2e23f7dc 830=item B<< $attr->has_clearer >>
5da16d1b 831
2e23f7dc 832=item B<< $attr->has_initializer >>
5da16d1b 833
2e23f7dc 834=item B<< $attr->has_init_arg >>
5da16d1b 835
2e23f7dc 836This will be I<false> if the C<init_arg> was set to C<undef>.
b25109b1 837
2e23f7dc 838=item B<< $attr->has_default >>
9e517e01 839
2e23f7dc 840This will be I<false> if the C<default> was set to C<undef>, since
841C<undef> is the default C<default> anyway.
9e517e01 842
2e23f7dc 843=item B<< $attr->has_builder >>
9e517e01 844
eeff7496 845=item B<< $attr->has_insertion_order >>
846
847This will be I<false> if this attribute has not be inserted into a class
848
552e3d24 849=back
850
2e23f7dc 851=head2 Value management
552e3d24 852
a6710c60 853These methods are basically "back doors" to the instance, and can be
2e23f7dc 854used to bypass the regular accessors, but still stay within the MOP.
855
856These methods are not for general use, and should only be used if you
857really know what you are doing.
fe122940 858
552e3d24 859=over 4
860
2e23f7dc 861=item B<< $attr->initialize_instance_slot($meta_instance, $instance, $params) >>
862
863This method is used internally to initialize the attribute's slot in
864the object C<$instance>.
865
866The C<$params> is a hash reference of the values passed to the object
867constructor.
868
869It's unlikely that you'll need to call this method yourself.
552e3d24 870
2e23f7dc 871=item B<< $attr->set_value($instance, $value) >>
552e3d24 872
2e23f7dc 873Sets the value without going through the accessor. Note that this
874works even with read-only attributes.
552e3d24 875
7e5efe15 876=item B<< $attr->set_raw_value($instance, $value) >>
877
878Sets the value with no side effects such as a trigger.
879
880This doesn't actually apply to Class::MOP attributes, only to subclasses.
881
2e23f7dc 882=item B<< $attr->set_initial_value($instance, $value) >>
c50c603e 883
2e23f7dc 884Sets the value without going through the accessor. This method is only
885called when the instance is first being initialized.
7d28758b 886
2e23f7dc 887=item B<< $attr->get_value($instance) >>
0ab65f99 888
2e23f7dc 889Returns the value without going through the accessor. Note that this
890works even with write-only accessors.
552e3d24 891
7e5efe15 892=item B<< $sttr->get_raw_value($instance) >>
893
894Returns the value without any side effects such as lazy attributes.
895
896Doesn't actually apply to Class::MOP attributes, only to subclasses.
897
2e23f7dc 898=item B<< $attr->has_value($instance) >>
552e3d24 899
2e23f7dc 900Return a boolean indicating whether the attribute has been set in
901C<$instance>. This how the default C<predicate> method works.
902
903=item B<< $attr->clear_value($instance) >>
904
905This will clear the attribute's value in C<$instance>. This is what
906the default C<clearer> calls.
907
908Note that this works even if the attribute does not have any
909associated read, write or clear methods.
bf731086 910
552e3d24 911=back
912
9ec169fe 913=head2 Class association
914
1d68af04 915These methods allow you to manage the attributes association with
916the class that contains it. These methods should not be used
2367814a 917lightly, nor are they very magical, they are mostly used internally
918and by metaclass instances.
919
9ec169fe 920=over 4
921
2e23f7dc 922=item B<< $attr->associated_class >>
923
924This returns the C<Class::MOP::Class> with which this attribute is
925associated, if any.
926
927=item B<< $attr->attach_to_class($metaclass) >>
9ec169fe 928
2e23f7dc 929This method stores a weakened reference to the C<$metaclass> object
930internally.
2367814a 931
2e23f7dc 932This method does not remove the attribute from its old class,
933nor does it create any accessors in the new class.
9ec169fe 934
2e23f7dc 935It is probably best to use the L<Class::MOP::Class> C<add_attribute>
936method instead.
2367814a 937
2e23f7dc 938=item B<< $attr->detach_from_class >>
9ec169fe 939
2e23f7dc 940This method removes the associate metaclass object from the attribute
941it has one.
942
943This method does not remove the attribute itself from the class, or
944remove its accessors.
945
946It is probably best to use the L<Class::MOP::Class>
947C<remove_attribute> method instead.
2367814a 948
9ec169fe 949=back
950
552e3d24 951=head2 Attribute Accessor generation
952
953=over 4
954
2e23f7dc 955=item B<< $attr->accessor_metaclass >>
ba38bf08 956
2e23f7dc 957Accessor methods are generated using an accessor metaclass. By
958default, this is L<Class::MOP::Method::Accessor>. This method returns
2367814a 959the name of the accessor metaclass that this attribute uses.
960
2e23f7dc 961=item B<< $attr->associate_method($method) >>
2367814a 962
2e23f7dc 963This associates a L<Class::MOP::Method> object with the
964attribute. Typically, this is called internally when an attribute
965generates its accessors.
3545c727 966
2e23f7dc 967=item B<< $attr->associated_methods >>
3545c727 968
2e23f7dc 969This returns the list of methods which have been associated with the
970attribute.
2367814a 971
2e23f7dc 972=item B<< $attr->install_accessors >>
2eb717d5 973
2e23f7dc 974This method generates and installs code the attributes various
975accessors. It is typically called from the L<Class::MOP::Class>
976C<add_attribute> method.
2eb717d5 977
2e23f7dc 978=item B<< $attr->remove_accessors >>
2eb717d5 979
2e23f7dc 980This method removes all of the accessors associated with the
981attribute.
2eb717d5 982
2e23f7dc 983This does not currently remove methods from the list returned by
984C<associated_methods>.
2367814a 985
2eb717d5 986=back
987
988=head2 Introspection
989
990=over 4
552e3d24 991
45b4c423 992=item B<< Class::MOP::Attribute->meta >>
552e3d24 993
2e23f7dc 994This will return a L<Class::MOP::Class> instance for this class.
fe122940 995
2e23f7dc 996It should also be noted that L<Class::MOP> will actually bootstrap
997this module by installing a number of attribute meta-objects into its
998metaclass.
fe122940 999
552e3d24 1000=back
1001
1a09d9cc 1002=head1 AUTHORS
8b978dd5 1003
a2e85e6c 1004Stevan Little E<lt>stevan@iinteractive.comE<gt>
8b978dd5 1005
1006=head1 COPYRIGHT AND LICENSE
1007
070bb6c9 1008Copyright 2006-2009 by Infinity Interactive, Inc.
8b978dd5 1009
1010L<http://www.iinteractive.com>
1011
1012This library is free software; you can redistribute it and/or modify
1d68af04 1013it under the same terms as Perl itself.
8b978dd5 1014
16e960bd 1015=cut
1016
7d28758b 1017