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