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