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