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