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