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