bump version to 0.82_02
[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
a0e95742 12our $VERSION = '0.82_02';
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 {
c7e28c19 332 Carp::cluck('The process_accessors method has been made private.'
333 . " The public version is deprecated and will be removed in a future release.\n");
e056bd42 334 shift->_process_accessors(@_);
45a183fb 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
76187047 498=item * init_arg
fe122940 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
d69fb6b3 504 MyClass->meta->new_object( -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
76187047 510=item * builder
1d68af04 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
76187047 516=item * default
4c4a6c41 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
76187047 566=item * initializer
0ef07b33 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
76187047 616=over 8
59e7697f 617
76187047 618=item * accessor
59e7697f 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
76187047 628=item * reader
59e7697f 629
2e23f7dc 630This is a basic read-only accessor. It returns the value of the
631attribute.
fe122940 632
76187047 633=item * writer
59e7697f 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
76187047 642=item * predicate
fe122940 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
76187047 650=item * clearer
7d28758b 651
2e23f7dc 652This method will uninitialize the attribute. After an attribute is
653cleared, its C<predicate> will return false.
7d28758b 654
76187047 655=item * definition_context
f8813817 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
76187047 687Returns the attribute's name.
688
2e23f7dc 689=item B<< $attr->accessor >>
2367814a 690
2e23f7dc 691=item B<< $attr->reader >>
16e960bd 692
2e23f7dc 693=item B<< $attr->writer >>
16e960bd 694
2e23f7dc 695=item B<< $attr->predicate >>
16e960bd 696
2e23f7dc 697=item B<< $attr->clearer >>
c0921932 698
2e23f7dc 699The C<accessor>, C<reader>, C<writer>, C<predicate>, and C<clearer>
700methods all return exactly what was passed to the constructor, so it
a6710c60 701can be either a string containing a method name, or a hash reference.
c0921932 702
2e23f7dc 703=item B<< $attr->initializer >>
16e960bd 704
a6710c60 705Returns the initializer as passed to the constructor, so this may be
2e23f7dc 706either a method name or a subroutine reference.
16e960bd 707
2e23f7dc 708=item B<< $attr->init_arg >>
3545c727 709
2e23f7dc 710=item B<< $attr->is_default_a_coderef >>
2367814a 711
2e23f7dc 712=item B<< $attr->default($instance) >>
3545c727 713
2e23f7dc 714The C<$instance> argument is optional. If you don't pass it, the
715return value for this method is exactly what was passed to the
716constructor, either a simple scalar or a subroutine reference.
2367814a 717
2e23f7dc 718If you I<do> pass an C<$instance> and the default is a subroutine
719reference, then the reference is called as a method on the
720C<$instance> and the generated value is returned.
16e960bd 721
2e23f7dc 722=item B<< $attr->slots >>
552e3d24 723
2e23f7dc 724Return a list of slots required by the attribute. This is usually just
725one, the name of the attribute.
fe122940 726
2e23f7dc 727A slot is the name of the hash key used to store the attribute in an
728object instance.
552e3d24 729
2e23f7dc 730=item B<< $attr->get_read_method >>
552e3d24 731
2e23f7dc 732=item B<< $attr->get_write_method >>
552e3d24 733
2e23f7dc 734Returns the name of a method suitable for reading or writing the value
735of the attribute in the associated class.
552e3d24 736
2e23f7dc 737If an attribute is read- or write-only, then these methods can return
738C<undef> as appropriate.
552e3d24 739
2e23f7dc 740=item B<< $attr->has_read_method >>
c50c603e 741
2e23f7dc 742=item B<< $attr->has_write_method >>
7d28758b 743
2e23f7dc 744This returns a boolean indicating whether the attribute has a I<named>
745read or write method.
0ab65f99 746
2e23f7dc 747=item B<< $attr->get_read_method_ref >>
552e3d24 748
2e23f7dc 749=item B<< $attr->get_write_method_ref >>
495af518 750
2e23f7dc 751Returns the subroutine reference of a method suitable for reading or
752writing the attribute's value in the associated class. These methods
753always return a subroutine reference, regardless of whether or not the
754attribute is read- or write-only.
755
756=back
fe122940 757
2e23f7dc 758=head2 Informational predicates
92d2abfa 759
2e23f7dc 760These are all basic predicate methods for the values passed into C<new>.
552e3d24 761
2e23f7dc 762=over 4
c57c8b10 763
2e23f7dc 764=item B<< $attr->has_accessor >>
c57c8b10 765
2e23f7dc 766=item B<< $attr->has_reader >>
b25109b1 767
2e23f7dc 768=item B<< $attr->has_writer >>
b25109b1 769
2e23f7dc 770=item B<< $attr->has_predicate >>
5da16d1b 771
2e23f7dc 772=item B<< $attr->has_clearer >>
5da16d1b 773
2e23f7dc 774=item B<< $attr->has_initializer >>
5da16d1b 775
2e23f7dc 776=item B<< $attr->has_init_arg >>
5da16d1b 777
2e23f7dc 778This will be I<false> if the C<init_arg> was set to C<undef>.
b25109b1 779
2e23f7dc 780=item B<< $attr->has_default >>
9e517e01 781
2e23f7dc 782This will be I<false> if the C<default> was set to C<undef>, since
783C<undef> is the default C<default> anyway.
9e517e01 784
2e23f7dc 785=item B<< $attr->has_builder >>
9e517e01 786
552e3d24 787=back
788
2e23f7dc 789=head2 Value management
552e3d24 790
a6710c60 791These methods are basically "back doors" to the instance, and can be
2e23f7dc 792used to bypass the regular accessors, but still stay within the MOP.
793
794These methods are not for general use, and should only be used if you
795really know what you are doing.
fe122940 796
552e3d24 797=over 4
798
2e23f7dc 799=item B<< $attr->initialize_instance_slot($meta_instance, $instance, $params) >>
800
801This method is used internally to initialize the attribute's slot in
802the object C<$instance>.
803
804The C<$params> is a hash reference of the values passed to the object
805constructor.
806
807It's unlikely that you'll need to call this method yourself.
552e3d24 808
2e23f7dc 809=item B<< $attr->set_value($instance, $value) >>
552e3d24 810
2e23f7dc 811Sets the value without going through the accessor. Note that this
812works even with read-only attributes.
552e3d24 813
2e23f7dc 814=item B<< $attr->set_initial_value($instance, $value) >>
c50c603e 815
2e23f7dc 816Sets the value without going through the accessor. This method is only
817called when the instance is first being initialized.
7d28758b 818
2e23f7dc 819=item B<< $attr->get_value($instance) >>
0ab65f99 820
2e23f7dc 821Returns the value without going through the accessor. Note that this
822works even with write-only accessors.
552e3d24 823
2e23f7dc 824=item B<< $attr->has_value($instance) >>
552e3d24 825
2e23f7dc 826Return a boolean indicating whether the attribute has been set in
827C<$instance>. This how the default C<predicate> method works.
828
829=item B<< $attr->clear_value($instance) >>
830
831This will clear the attribute's value in C<$instance>. This is what
832the default C<clearer> calls.
833
834Note that this works even if the attribute does not have any
835associated read, write or clear methods.
bf731086 836
552e3d24 837=back
838
9ec169fe 839=head2 Class association
840
1d68af04 841These methods allow you to manage the attributes association with
842the class that contains it. These methods should not be used
2367814a 843lightly, nor are they very magical, they are mostly used internally
844and by metaclass instances.
845
9ec169fe 846=over 4
847
2e23f7dc 848=item B<< $attr->associated_class >>
849
850This returns the C<Class::MOP::Class> with which this attribute is
851associated, if any.
852
853=item B<< $attr->attach_to_class($metaclass) >>
9ec169fe 854
2e23f7dc 855This method stores a weakened reference to the C<$metaclass> object
856internally.
2367814a 857
2e23f7dc 858This method does not remove the attribute from its old class,
859nor does it create any accessors in the new class.
9ec169fe 860
2e23f7dc 861It is probably best to use the L<Class::MOP::Class> C<add_attribute>
862method instead.
2367814a 863
2e23f7dc 864=item B<< $attr->detach_from_class >>
9ec169fe 865
2e23f7dc 866This method removes the associate metaclass object from the attribute
867it has one.
868
869This method does not remove the attribute itself from the class, or
870remove its accessors.
871
872It is probably best to use the L<Class::MOP::Class>
873C<remove_attribute> method instead.
2367814a 874
9ec169fe 875=back
876
552e3d24 877=head2 Attribute Accessor generation
878
879=over 4
880
2e23f7dc 881=item B<< $attr->accessor_metaclass >>
ba38bf08 882
2e23f7dc 883Accessor methods are generated using an accessor metaclass. By
884default, this is L<Class::MOP::Method::Accessor>. This method returns
2367814a 885the name of the accessor metaclass that this attribute uses.
886
2e23f7dc 887=item B<< $attr->associate_method($method) >>
2367814a 888
2e23f7dc 889This associates a L<Class::MOP::Method> object with the
890attribute. Typically, this is called internally when an attribute
891generates its accessors.
3545c727 892
2e23f7dc 893=item B<< $attr->associated_methods >>
3545c727 894
2e23f7dc 895This returns the list of methods which have been associated with the
896attribute.
2367814a 897
2e23f7dc 898=item B<< $attr->install_accessors >>
2eb717d5 899
2e23f7dc 900This method generates and installs code the attributes various
901accessors. It is typically called from the L<Class::MOP::Class>
902C<add_attribute> method.
2eb717d5 903
2e23f7dc 904=item B<< $attr->remove_accessors >>
2eb717d5 905
2e23f7dc 906This method removes all of the accessors associated with the
907attribute.
2eb717d5 908
2e23f7dc 909This does not currently remove methods from the list returned by
910C<associated_methods>.
2367814a 911
2eb717d5 912=back
913
914=head2 Introspection
915
916=over 4
552e3d24 917
45b4c423 918=item B<< Class::MOP::Attribute->meta >>
552e3d24 919
2e23f7dc 920This will return a L<Class::MOP::Class> instance for this class.
fe122940 921
2e23f7dc 922It should also be noted that L<Class::MOP> will actually bootstrap
923this module by installing a number of attribute meta-objects into its
924metaclass.
fe122940 925
552e3d24 926=back
927
1a09d9cc 928=head1 AUTHORS
8b978dd5 929
a2e85e6c 930Stevan Little E<lt>stevan@iinteractive.comE<gt>
8b978dd5 931
932=head1 COPYRIGHT AND LICENSE
933
070bb6c9 934Copyright 2006-2009 by Infinity Interactive, Inc.
8b978dd5 935
936L<http://www.iinteractive.com>
937
938This library is free software; you can redistribute it and/or modify
1d68af04 939it under the same terms as Perl itself.
8b978dd5 940
16e960bd 941=cut
942
7d28758b 943