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