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