changelog
[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';
9ec169fe 10use Scalar::Util 'blessed', 'reftype', 'weaken';
2eb717d5 11
0c6f4c4a 12our $VERSION = '0.23';
f0480c45 13our $AUTHORITY = 'cpan:STEVAN';
8b978dd5 14
b1897d4d 15use base 'Class::MOP::Object';
16
1d68af04 17sub meta {
727919c5 18 require Class::MOP::Class;
aa448b16 19 Class::MOP::Class->initialize(blessed($_[0]) || $_[0]);
727919c5 20}
2eb717d5 21
727919c5 22# NOTE: (meta-circularity)
1d68af04 23# This method will be replaced in the
24# boostrap section of Class::MOP, by
25# a new version which uses the
727919c5 26# &Class::MOP::Class::construct_instance
27# method to build an attribute meta-object
28# which itself is described with attribute
1d68af04 29# meta-objects.
727919c5 30# - Ain't meta-circularity grand? :)
8b978dd5 31sub new {
32 my $class = shift;
33 my $name = shift;
1d68af04 34 my %options = @_;
35
cbd9f942 36 (defined $name && $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 {
47 (is_default_a_coderef(\%options))
48 || confess("References are not allowed as default values, you must ".
49 "wrap then in a CODE reference (ex: sub { [] } and not [])")
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 }
8b978dd5 55 bless {
c23184fc 56 '$!name' => $name,
57 '$!accessor' => $options{accessor},
58 '$!reader' => $options{reader},
2e877f58 59 # NOTE:
60 # protect this from silliness
61 init_arg => '!............( DO NOT DO THIS )............!',
c23184fc 62 '$!writer' => $options{writer},
63 '$!predicate' => $options{predicate},
64 '$!clearer' => $options{clearer},
1d68af04 65 '$!builder' => $options{builder},
c23184fc 66 '$!init_arg' => $options{init_arg},
67 '$!default' => $options{default},
1d68af04 68 # keep a weakened link to the
9ec169fe 69 # class we are associated with
c23184fc 70 '$!associated_class' => undef,
0ab65f99 71 '$!initializer' => $options{initializer},
1d68af04 72 # and a list of the methods
3545c727 73 # associated with this attr
c23184fc 74 '@!associated_methods' => [],
8b978dd5 75 } => $class;
76}
77
7b31baf4 78# NOTE:
1d68af04 79# this is a primative (and kludgy) clone operation
16e960bd 80# for now, it will be replaced in the Class::MOP
1d68af04 81# bootstrap with a proper one, however we know
5659d76e 82# that this one will work fine for now.
83sub clone {
84 my $self = shift;
85 my %options = @_;
86 (blessed($self))
87 || confess "Can only clone an instance";
88 return bless { %{$self}, %options } => blessed($self);
89}
90
bd4e03f9 91sub initialize_instance_slot {
f892c0f0 92 my ($self, $meta_instance, $instance, $params) = @_;
c23184fc 93 my $init_arg = $self->{'$!init_arg'};
bd4e03f9 94 # try to fetch the init arg from the %params ...
8d2d4c67 95
1d68af04 96 # if nothing was in the %params, we can use the
bd4e03f9 97 # attribute's default value (if it has one)
2e877f58 98 if(defined $init_arg and exists $params->{$init_arg}){
0ab65f99 99 $meta_instance->_set_initial_slot_value(
100 $instance,
101 $self->name,
102 $params->{$init_arg},
103 $self->initializer,
104 );
b7bdffc3 105 }
106 elsif (defined $self->{'$!default'}) {
0ab65f99 107 $meta_instance->_set_initial_slot_value(
108 $instance,
109 $self->name,
110 $self->default($instance),
111 $self->initializer,
112 );
b7bdffc3 113 }
114 elsif (defined( my $builder = $self->{'$!builder'})) {
115 if ($builder = $instance->can($builder)) {
0ab65f99 116 $meta_instance->_set_initial_slot_value(
117 $instance,
118 $self->name,
119 $instance->$builder,
120 $self->initializer,
121 );
b7bdffc3 122 }
123 else {
232c4e13 124 confess(blessed($instance)." does not support builder method '". $self->{'$!builder'} ."' for attribute '" . $self->name . "'");
8fe581e5 125 }
1d68af04 126 }
bd4e03f9 127}
128
5659d76e 129# NOTE:
1d68af04 130# the next bunch of methods will get bootstrapped
7b31baf4 131# away in the Class::MOP bootstrapping section
132
c23184fc 133sub name { $_[0]->{'$!name'} }
c50c603e 134
c23184fc 135sub associated_class { $_[0]->{'$!associated_class'} }
136sub associated_methods { $_[0]->{'@!associated_methods'} }
7b31baf4 137
c23184fc 138sub has_accessor { defined($_[0]->{'$!accessor'}) ? 1 : 0 }
139sub has_reader { defined($_[0]->{'$!reader'}) ? 1 : 0 }
140sub has_writer { defined($_[0]->{'$!writer'}) ? 1 : 0 }
141sub has_predicate { defined($_[0]->{'$!predicate'}) ? 1 : 0 }
142sub has_clearer { defined($_[0]->{'$!clearer'}) ? 1 : 0 }
1d68af04 143sub has_builder { defined($_[0]->{'$!builder'}) ? 1 : 0 }
c23184fc 144sub has_init_arg { defined($_[0]->{'$!init_arg'}) ? 1 : 0 }
145sub has_default { defined($_[0]->{'$!default'}) ? 1 : 0 }
0ab65f99 146sub has_initializer { defined($_[0]->{'$!initializer'}) ? 1 : 0 }
c50c603e 147
1d68af04 148sub accessor { $_[0]->{'$!accessor'} }
c23184fc 149sub reader { $_[0]->{'$!reader'} }
150sub writer { $_[0]->{'$!writer'} }
151sub predicate { $_[0]->{'$!predicate'} }
152sub clearer { $_[0]->{'$!clearer'} }
1d68af04 153sub builder { $_[0]->{'$!builder'} }
c23184fc 154sub init_arg { $_[0]->{'$!init_arg'} }
0ab65f99 155sub initializer { $_[0]->{'$!initializer'} }
c50c603e 156
7b31baf4 157# end bootstrapped away method section.
158# (all methods below here are kept intact)
159
d14f6cbe 160sub get_read_method {
161 my $self = shift;
162 my $reader = $self->reader || $self->accessor;
163 # normal case ...
164 return $reader unless ref $reader;
165 # the HASH ref case
166 my ($name) = %$reader;
167 return $name;
168}
169
170sub get_write_method {
171 my $self = shift;
172 my $writer = $self->writer || $self->accessor;
173 # normal case ...
174 return $writer unless ref $writer;
175 # the HASH ref case
176 my ($name) = %$writer;
177 return $name;
178}
b25109b1 179
5da16d1b 180sub get_read_method_ref {
181 my $self = shift;
742fb371 182 if ((my $reader = $self->get_read_method) && $self->associated_class) {
5da16d1b 183 return $self->associated_class->get_method($reader);
184 }
185 else {
186 return sub { $self->get_value(@_) };
187 }
188}
189
190sub get_write_method_ref {
191 my $self = shift;
d14f6cbe 192 if ((my $writer = $self->get_write_method) && $self->associated_class) {
742fb371 193 return $self->associated_class->get_method($writer);
5da16d1b 194 }
195 else {
196 return sub { $self->set_value(@_) };
197 }
198}
199
1d68af04 200sub is_default_a_coderef {
201 ('CODE' eq (reftype($_[0]->{'$!default'} || $_[0]->{default}) || ''))
c0cbf4d9 202}
203
1d68af04 204sub default {
c0cbf4d9 205 my ($self, $instance) = @_;
9363ea89 206 if (defined $instance && $self->is_default_a_coderef) {
1d68af04 207 # if the default is a CODE ref, then
727919c5 208 # we pass in the instance and default
1d68af04 209 # can return a value based on that
727919c5 210 # instance. Somewhat crude, but works.
c23184fc 211 return $self->{'$!default'}->($instance);
1d68af04 212 }
c23184fc 213 $self->{'$!default'};
c50c603e 214}
8b978dd5 215
c57c8b10 216# slots
217
218sub slots { (shift)->name }
219
1d68af04 220# class association
727919c5 221
9ec169fe 222sub attach_to_class {
223 my ($self, $class) = @_;
224 (blessed($class) && $class->isa('Class::MOP::Class'))
225 || confess "You must pass a Class::MOP::Class instance (or a subclass)";
1d68af04 226 weaken($self->{'$!associated_class'} = $class);
9ec169fe 227}
228
229sub detach_from_class {
230 my $self = shift;
1d68af04 231 $self->{'$!associated_class'} = undef;
9ec169fe 232}
233
1d68af04 234# method association
3545c727 235
236sub associate_method {
237 my ($self, $method) = @_;
c23184fc 238 push @{$self->{'@!associated_methods'}} => $method;
3545c727 239}
240
16e960bd 241## Slot management
242
ef91a0e2 243sub set_initial_value {
244 my ($self, $instance, $value) = @_;
245
246 Class::MOP::Class->initialize(blessed($instance))
247 ->get_meta_instance
248 ->_set_initial_slot_value($instance, $self->name, $value, $self->initializer);
249}
250
16e960bd 251sub set_value {
1396f86b 252 my ($self, $instance, $value) = @_;
16e960bd 253
3545c727 254 Class::MOP::Class->initialize(blessed($instance))
16e960bd 255 ->get_meta_instance
3545c727 256 ->set_slot_value($instance, $self->name, $value);
16e960bd 257}
258
259sub get_value {
1396f86b 260 my ($self, $instance) = @_;
16e960bd 261
3545c727 262 Class::MOP::Class->initialize(blessed($instance))
16e960bd 263 ->get_meta_instance
1396f86b 264 ->get_slot_value($instance, $self->name);
16e960bd 265}
266
3545c727 267sub has_value {
268 my ($self, $instance) = @_;
1d68af04 269
8d2d4c67 270 Class::MOP::Class->initialize(blessed($instance))
271 ->get_meta_instance
272 ->is_slot_initialized($instance, $self->name);
3545c727 273}
274
275sub clear_value {
276 my ($self, $instance) = @_;
1d68af04 277
3545c727 278 Class::MOP::Class->initialize(blessed($instance))
279 ->get_meta_instance
1d68af04 280 ->deinitialize_slot($instance, $self->name);
3545c727 281}
282
ba38bf08 283## load em up ...
c0cbf4d9 284
ba38bf08 285sub accessor_metaclass { 'Class::MOP::Method::Accessor' }
c0cbf4d9 286
9ec169fe 287sub process_accessors {
c0cbf4d9 288 my ($self, $type, $accessor, $generate_as_inline_methods) = @_;
013b1897 289 if (reftype($accessor)) {
290 (reftype($accessor) eq 'HASH')
7d28758b 291 || confess "bad accessor/reader/writer/predicate/clearer format, must be a HASH ref";
4d47b77f 292 my ($name, $method) = %{$accessor};
3545c727 293 $method = $self->accessor_metaclass->wrap($method);
294 $self->associate_method($method);
1d68af04 295 return ($name, $method);
2eb717d5 296 }
9ec169fe 297 else {
1d68af04 298 my $inline_me = ($generate_as_inline_methods && $self->associated_class->instance_metaclass->is_inlinable);
ba38bf08 299 my $method;
300 eval {
301 $method = $self->accessor_metaclass->new(
302 attribute => $self,
d90b42a6 303 is_inline => $inline_me,
ba38bf08 304 accessor_type => $type,
1d68af04 305 );
ba38bf08 306 };
1d68af04 307 confess "Could not create the '$type' method for " . $self->name . " because : $@" if $@;
3545c727 308 $self->associate_method($method);
ba38bf08 309 return ($accessor, $method);
1d68af04 310 }
9ec169fe 311}
312
313sub install_accessors {
c0cbf4d9 314 my $self = shift;
315 my $inline = shift;
316 my $class = $self->associated_class;
1d68af04 317
9ec169fe 318 $class->add_method(
c0cbf4d9 319 $self->process_accessors('accessor' => $self->accessor(), $inline)
9ec169fe 320 ) if $self->has_accessor();
321
1d68af04 322 $class->add_method(
c0cbf4d9 323 $self->process_accessors('reader' => $self->reader(), $inline)
9ec169fe 324 ) if $self->has_reader();
325
326 $class->add_method(
c0cbf4d9 327 $self->process_accessors('writer' => $self->writer(), $inline)
9ec169fe 328 ) if $self->has_writer();
329
330 $class->add_method(
c0cbf4d9 331 $self->process_accessors('predicate' => $self->predicate(), $inline)
9ec169fe 332 ) if $self->has_predicate();
1d68af04 333
7d28758b 334 $class->add_method(
335 $self->process_accessors('clearer' => $self->clearer(), $inline)
336 ) if $self->has_clearer();
1d68af04 337
9ec169fe 338 return;
2eb717d5 339}
340
b51af7f9 341{
342 my $_remove_accessor = sub {
343 my ($accessor, $class) = @_;
c50c603e 344 if (reftype($accessor) && reftype($accessor) eq 'HASH') {
345 ($accessor) = keys %{$accessor};
1d68af04 346 }
347 my $method = $class->get_method($accessor);
348 $class->remove_method($accessor)
ba38bf08 349 if (blessed($method) && $method->isa('Class::MOP::Method::Accessor'));
b51af7f9 350 };
1d68af04 351
b51af7f9 352 sub remove_accessors {
9ec169fe 353 my $self = shift;
2367814a 354 # TODO:
1d68af04 355 # we really need to make sure to remove from the
356 # associates methods here as well. But this is
357 # such a slimly used method, I am not worried
2367814a 358 # about it right now.
9ec169fe 359 $_remove_accessor->($self->accessor(), $self->associated_class()) if $self->has_accessor();
360 $_remove_accessor->($self->reader(), $self->associated_class()) if $self->has_reader();
361 $_remove_accessor->($self->writer(), $self->associated_class()) if $self->has_writer();
362 $_remove_accessor->($self->predicate(), $self->associated_class()) if $self->has_predicate();
7d28758b 363 $_remove_accessor->($self->clearer(), $self->associated_class()) if $self->has_clearer();
1d68af04 364 return;
b51af7f9 365 }
366
8b978dd5 367}
368
3691;
370
371__END__
372
373=pod
374
1d68af04 375=head1 NAME
8b978dd5 376
377Class::MOP::Attribute - Attribute Meta Object
378
379=head1 SYNOPSIS
1d68af04 380
8b978dd5 381 Class::MOP::Attribute->new('$foo' => (
fe122940 382 accessor => 'foo', # dual purpose get/set accessor
1d68af04 383 predicate => 'has_foo' # predicate check for defined-ness
fe122940 384 init_arg => '-foo', # class->new will look for a -foo key
385 default => 'BAR IS BAZ!' # if no -foo key is provided, use this
8b978dd5 386 ));
1d68af04 387
8b978dd5 388 Class::MOP::Attribute->new('$.bar' => (
fe122940 389 reader => 'bar', # getter
1d68af04 390 writer => 'set_bar', # setter
391 predicate => 'has_bar' # predicate check for defined-ness
fe122940 392 init_arg => ':bar', # class->new will look for a :bar key
8b978dd5 393 # no default value means it is undef
394 ));
395
396=head1 DESCRIPTION
397
fe122940 398The Attribute Protocol is almost entirely an invention of this module,
1d68af04 399and is completely optional to this MOP. This is because Perl 5 does not
400have consistent notion of what is an attribute of a class. There are
401so many ways in which this is done, and very few (if any) are
fe122940 402easily discoverable by this module.
552e3d24 403
1d68af04 404So, all that said, this module attempts to inject some order into this
405chaos, by introducing a consistent API which can be used to create
fe122940 406object attributes.
552e3d24 407
408=head1 METHODS
409
410=head2 Creation
411
412=over 4
413
fe122940 414=item B<new ($name, ?%options)>
415
1d68af04 416An attribute must (at the very least), have a C<$name>. All other
a2e85e6c 417C<%options> are contained added as key-value pairs. Acceptable keys
fe122940 418are as follows:
419
420=over 4
421
422=item I<init_arg>
423
1d68af04 424This should be a string value representing the expected key in
425an initialization hash. For instance, if we have an I<init_arg>
fe122940 426value of C<-foo>, then the following code will Just Work.
427
428 MyClass->meta->construct_instance(-foo => "Hello There");
429
1d68af04 430In an init_arg is not assigned, it will automatically use the
7b31baf4 431value of C<$name>.
432
1d68af04 433=item I<builder>
434
435The value of this key is the name of the method that will be
436called to obtain the value used to initialize the attribute.
437This should be a method in the class associated with the attribute,
438not a method in the attribute class itself.
fe122940 439
4c4a6c41 440=item I<default>
441
442The value of this key is the default value which
443C<Class::MOP::Class::construct_instance> will initialize the
444attribute to.
445
fe122940 446B<NOTE:>
1d68af04 447If the value is a simple scalar (string or number), then it can
448be just passed as is. However, if you wish to initialize it with
449a HASH or ARRAY ref, then you need to wrap that inside a CODE
fe122940 450reference, like so:
451
452 Class::MOP::Attribute->new('@foo' => (
453 default => sub { [] },
454 ));
1d68af04 455
456 # or ...
457
fe122940 458 Class::MOP::Attribute->new('%foo' => (
459 default => sub { {} },
1d68af04 460 ));
fe122940 461
1d68af04 462If you wish to initialize an attribute with a CODE reference
fe122940 463itself, then you need to wrap that in a subroutine as well, like
464so:
1d68af04 465
fe122940 466 Class::MOP::Attribute->new('&foo' => (
467 default => sub { sub { print "Hello World" } },
468 ));
469
1d68af04 470And lastly, if the value of your attribute is dependent upon
471some other aspect of the instance structure, then you can take
472advantage of the fact that when the I<default> value is a CODE
473reference, it is passed the raw (unblessed) instance structure
fe122940 474as it's only argument. So you can do things like this:
475
476 Class::MOP::Attribute->new('$object_identity' => (
477 default => sub { Scalar::Util::refaddr($_[0]) },
478 ));
479
1d68af04 480This last feature is fairly limited as there is no gurantee of
481the order of attribute initializations, so you cannot perform
482any kind of dependent initializations. However, if this is
483something you need, you could subclass B<Class::MOP::Class> and
484this class to acheive it. However, this is currently left as
fe122940 485an exercise to the reader :).
486
487=back
488
7d28758b 489The I<accessor>, I<reader>, I<writer>, I<predicate> and I<clearer> keys can
490contain either; the name of the method and an appropriate default one will be
491generated for you, B<or> a HASH ref containing exactly one key (which will be
492used as the name of the method) and one value, which should contain a CODE
493reference which will be installed as the method itself.
59e7697f 494
495=over 4
496
497=item I<accessor>
498
1d68af04 499The I<accessor> is a standard perl-style read/write accessor. It will
500return the value of the attribute, and if a value is passed as an argument,
fe122940 501it will assign that value to the attribute.
502
503B<NOTE:>
1d68af04 504This method will properly handle the following code, by assigning an
fe122940 505C<undef> value to the attribute.
506
507 $object->set_something(undef);
508
59e7697f 509=item I<reader>
510
1d68af04 511This is a basic read-only accessor, it will just return the value of
fe122940 512the attribute.
513
59e7697f 514=item I<writer>
515
1d68af04 516This is a basic write accessor, it accepts a single argument, and
517assigns that value to the attribute. This method does not intentially
518return a value, however perl will return the result of the last
519expression in the subroutine, which returns in this returning the
520same value that it was passed.
59e7697f 521
fe122940 522B<NOTE:>
1d68af04 523This method will properly handle the following code, by assigning an
fe122940 524C<undef> value to the attribute.
59e7697f 525
fe122940 526 $object->set_something();
527
528=item I<predicate>
529
07dca7e3 530This is a basic test to see if any value has been set for the
531attribute. It will return true (C<1>) if the attribute has been set
532to any value (even C<undef>), and false (C<0>) otherwise.
533
534B<NOTE:>
535The predicate will return true even when you set an attribute's
536value to C<undef>. This behaviour has changed as of version 0.43. In
537older versions, the predicate (erroneously) checked for attribute
538value definedness, instead of presence as it is now.
539
540If you really want to get rid of the value, you have to define and
541use a I<clearer> (see below).
542
59e7697f 543
7d28758b 544=item I<clearer>
545
546This is the a method that will uninitialize the attr, reverting lazy values
547back to their "unfulfilled" state.
548
59e7697f 549=back
552e3d24 550
bd4e03f9 551=item B<clone (%options)>
552
553=item B<initialize_instance_slot ($instance, $params)>
554
1d68af04 555=back
552e3d24 556
16e960bd 557=head2 Value management
558
1d68af04 559These methods are basically "backdoors" to the instance, which can be used
560to bypass the regular accessors, but still stay within the context of the MOP.
2367814a 561
1d68af04 562These methods are not for general use, and should only be used if you really
2367814a 563know what you are doing.
564
16e960bd 565=over 4
566
3545c727 567=item B<set_value ($instance, $value)>
16e960bd 568
569Set the value without going through the accessor. Note that this may be done to
570even attributes with just read only accessors.
571
c0921932 572=item B<set_initial_value ($instance, $value)>
573
574This method sets the value without going through the accessor -- but it is only
575called when the instance data is first initialized.
576
3545c727 577=item B<get_value ($instance)>
16e960bd 578
579Return the value without going through the accessor. Note that this may be done
580even to attributes with just write only accessors.
581
3545c727 582=item B<has_value ($instance)>
583
92d2abfa 584Return a boolean indicating if the item in the C<$instance> has a value in it.
2367814a 585This is basically what the default C<predicate> method calls.
586
3545c727 587=item B<clear_value ($instance)>
588
2367814a 589This will clear the value in the C<$instance>. This is basically what the default
1d68af04 590C<clearer> would call. Note that this may be done even if the attirbute does not
2367814a 591have any associated read, write or clear methods.
592
16e960bd 593=back
594
552e3d24 595=head2 Informational
596
1d68af04 597These are all basic read-only value accessors for the values
fe122940 598passed into C<new>. I think they are pretty much self-explanitory.
599
552e3d24 600=over 4
601
602=item B<name>
603
604=item B<accessor>
605
606=item B<reader>
607
608=item B<writer>
609
c50c603e 610=item B<predicate>
611
7d28758b 612=item B<clearer>
613
0ab65f99 614=item B<initializer>
615
552e3d24 616=item B<init_arg>
617
495af518 618=item B<is_default_a_coderef>
619
fe122940 620=item B<default (?$instance)>
621
92d2abfa 622Return the default value for the attribute.
623
624If you pass in an C<$instance> argument to this accessor and the
625I<default> is a CODE reference, then the CODE reference will be
626executed with the C<$instance> as its argument.
552e3d24 627
c57c8b10 628=item B<slots>
629
92d2abfa 630Return a list of slots required by the attribute. This is usually
c57c8b10 631just one, which is the name of the attribute.
632
b25109b1 633=item B<get_read_method>
634
635=item B<get_write_method>
636
5da16d1b 637Return the name of a method name suitable for reading / writing the value
638of the attribute in the associated class. Suitable for use whether
639C<reader> and C<writer> or C<accessor> was used.
640
641=item B<get_read_method_ref>
642
643=item B<get_write_method_ref>
644
645Return the CODE reference of a method suitable for reading / writing the
646value of the attribute in the associated class. Suitable for use whether
647C<reader> and C<writer> or C<accessor> was specified or not.
648
649NOTE: If not reader/writer/accessor was specified, this will use the
650attribute get_value/set_value methods, which can be very inefficient.
b25109b1 651
552e3d24 652=back
653
654=head2 Informational predicates
655
a2e85e6c 656These are all basic predicate methods for the values passed into C<new>.
fe122940 657
552e3d24 658=over 4
659
660=item B<has_accessor>
661
552e3d24 662=item B<has_reader>
663
552e3d24 664=item B<has_writer>
665
c50c603e 666=item B<has_predicate>
667
7d28758b 668=item B<has_clearer>
669
0ab65f99 670=item B<has_initializer>
671
552e3d24 672=item B<has_init_arg>
673
552e3d24 674=item B<has_default>
675
bf731086 676=item B<has_builder>
677
552e3d24 678=back
679
9ec169fe 680=head2 Class association
681
1d68af04 682These methods allow you to manage the attributes association with
683the class that contains it. These methods should not be used
2367814a 684lightly, nor are they very magical, they are mostly used internally
685and by metaclass instances.
686
9ec169fe 687=over 4
688
689=item B<associated_class>
690
2367814a 691This returns the metaclass this attribute is associated with.
692
9ec169fe 693=item B<attach_to_class ($class)>
694
1d68af04 695This will store a weaken reference to C<$class> internally. You should
2367814a 696note that just changing the class assocation will not remove the attribute
697from it's old class, and initialize it (and it's accessors) in the new
698C<$class>. It is up to you to do this manually.
699
9ec169fe 700=item B<detach_from_class>
701
1d68af04 702This will remove the weakened reference to the class. It does B<not>
703remove the attribute itself from the class (or remove it's accessors),
704you must do that yourself if you want too. Actually if that is what
705you want to do, you should probably be looking at
2367814a 706L<Class::MOP::Class::remove_attribute> instead.
707
9ec169fe 708=back
709
552e3d24 710=head2 Attribute Accessor generation
711
712=over 4
713
ba38bf08 714=item B<accessor_metaclass>
715
2367814a 716Accessors are generated by an accessor metaclass, which is usually
1d68af04 717a subclass of C<Class::MOP::Method::Accessor>. This method returns
2367814a 718the name of the accessor metaclass that this attribute uses.
719
720=item B<associate_method ($method)>
721
1d68af04 722This will associate a C<$method> with the given attribute which is
723used internally by the accessor generator.
3545c727 724
725=item B<associated_methods>
726
1d68af04 727This will return the list of methods which have been associated with
728the C<associate_method> methods.
2367814a 729
9ec169fe 730=item B<install_accessors>
2eb717d5 731
1d68af04 732This allows the attribute to generate and install code for it's own
733I<accessor/reader/writer/predicate> methods. This is called by
fe122940 734C<Class::MOP::Class::add_attribute>.
2eb717d5 735
1d68af04 736This method will call C<process_accessors> for each of the possible
9ec169fe 737method types (accessor, reader, writer & predicate).
738
739=item B<process_accessors ($type, $value)>
740
1d68af04 741This takes a C<$type> (accessor, reader, writer or predicate), and
9ec169fe 742a C<$value> (the value passed into the constructor for each of the
1d68af04 743different types). It will then either generate the method itself
744(using the C<generate_*_method> methods listed below) or it will
745use the custom method passed through the constructor.
9ec169fe 746
9ec169fe 747=item B<remove_accessors>
2eb717d5 748
1d68af04 749This allows the attribute to remove the method for it's own
750I<accessor/reader/writer/predicate/clearer>. This is called by
fe122940 751C<Class::MOP::Class::remove_attribute>.
2eb717d5 752
1d68af04 753NOTE: This does not currently remove methods from the list returned
2367814a 754by C<associated_methods>, that is on the TODO list.
755
2eb717d5 756=back
757
758=head2 Introspection
759
760=over 4
552e3d24 761
2eb717d5 762=item B<meta>
552e3d24 763
1d68af04 764This will return a B<Class::MOP::Class> instance which is related
fe122940 765to this class.
766
1d68af04 767It should also be noted that B<Class::MOP> will actually bootstrap
768this module by installing a number of attribute meta-objects into
769it's metaclass. This will allow this class to reap all the benifits
770of the MOP when subclassing it.
fe122940 771
552e3d24 772=back
773
1a09d9cc 774=head1 AUTHORS
8b978dd5 775
a2e85e6c 776Stevan Little E<lt>stevan@iinteractive.comE<gt>
8b978dd5 777
778=head1 COPYRIGHT AND LICENSE
779
69e3ab0a 780Copyright 2006-2008 by Infinity Interactive, Inc.
8b978dd5 781
782L<http://www.iinteractive.com>
783
784This library is free software; you can redistribute it and/or modify
1d68af04 785it under the same terms as Perl itself.
8b978dd5 786
16e960bd 787=cut
788
7d28758b 789