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