stop closing over the method metaobject
[gitmo/Moose.git] / lib / Moose / Meta / Attribute.pm
1
2 package Moose::Meta::Attribute;
3
4 use strict;
5 use warnings;
6
7 use Class::MOP ();
8 use B ();
9 use Scalar::Util 'blessed', 'weaken';
10 use List::MoreUtils 'any';
11 use Try::Tiny;
12 use overload     ();
13
14 use Moose::Deprecated;
15 use Moose::Meta::Method::Accessor;
16 use Moose::Meta::Method::Delegation;
17 use Moose::Util ();
18 use Moose::Util::TypeConstraints ();
19 use Class::MOP::MiniTrait;
20
21 use base 'Class::MOP::Attribute', 'Moose::Meta::Mixin::AttributeCore';
22
23 Class::MOP::MiniTrait::apply(__PACKAGE__, 'Moose::Meta::Object::Trait');
24
25 __PACKAGE__->meta->add_attribute('traits' => (
26     reader    => 'applied_traits',
27     predicate => 'has_applied_traits',
28 ));
29
30 # we need to have a ->does method in here to
31 # more easily support traits, and the introspection
32 # of those traits. We extend the does check to look
33 # for metatrait aliases.
34 sub does {
35     my ($self, $role_name) = @_;
36     my $name = try {
37         Moose::Util::resolve_metatrait_alias(Attribute => $role_name)
38     };
39     return 0 if !defined($name); # failed to load class
40     return $self->Moose::Object::does($name);
41 }
42
43 sub _error_thrower {
44     my $self = shift;
45     require Moose::Meta::Class;
46     ( ref $self && $self->associated_class ) || "Moose::Meta::Class";
47 }
48
49 sub throw_error {
50     my $self = shift;
51     my $inv = $self->_error_thrower;
52     unshift @_, "message" if @_ % 2 == 1;
53     unshift @_, attr => $self if ref $self;
54     unshift @_, $inv;
55     my $handler = $inv->can("throw_error"); # to avoid incrementing depth by 1
56     goto $handler;
57 }
58
59 sub _inline_throw_error {
60     my ( $self, $msg, $args ) = @_;
61
62     my $inv = $self->_error_thrower;
63     # XXX ugh
64     $inv = 'Moose::Meta::Class' unless $inv->can('_inline_throw_error');
65
66     # XXX ugh ugh UGH
67     my $class = $self->associated_class;
68     if ($class) {
69         my $class_name = B::perlstring($class->name);
70         my $attr_name = B::perlstring($self->name);
71         $args = 'attr => Class::MOP::class_of(' . $class_name . ')'
72               . '->find_attribute_by_name(' . $attr_name . '), '
73               . (defined $args ? $args : '');
74     }
75
76     return $inv->_inline_throw_error($msg, $args)
77 }
78
79 sub new {
80     my ($class, $name, %options) = @_;
81     $class->_process_options($name, \%options) unless $options{__hack_no_process_options}; # used from clone()... YECHKKK FIXME ICKY YUCK GROSS
82     
83     delete $options{__hack_no_process_options};
84
85     my %attrs =
86         ( map { $_ => 1 }
87           grep { defined }
88           map { $_->init_arg() }
89           $class->meta()->get_all_attributes()
90         );
91
92     my @bad = sort grep { ! $attrs{$_} }  keys %options;
93
94     if (@bad)
95     {
96         Carp::cluck "Found unknown argument(s) passed to '$name' attribute constructor in '$class': @bad";
97     }
98
99     return $class->SUPER::new($name, %options);
100 }
101
102 sub interpolate_class_and_new {
103     my ($class, $name, %args) = @_;
104
105     my ( $new_class, @traits ) = $class->interpolate_class(\%args);
106
107     $new_class->new($name, %args, ( scalar(@traits) ? ( traits => \@traits ) : () ) );
108 }
109
110 sub interpolate_class {
111     my ($class, $options) = @_;
112
113     $class = ref($class) || $class;
114
115     if ( my $metaclass_name = delete $options->{metaclass} ) {
116         my $new_class = Moose::Util::resolve_metaclass_alias( Attribute => $metaclass_name );
117
118         if ( $class ne $new_class ) {
119             if ( $new_class->can("interpolate_class") ) {
120                 return $new_class->interpolate_class($options);
121             } else {
122                 $class = $new_class;
123             }
124         }
125     }
126
127     my @traits;
128
129     if (my $traits = $options->{traits}) {
130         my $i = 0;
131         while ($i < @$traits) {
132             my $trait = $traits->[$i++];
133             next if ref($trait); # options to a trait we discarded
134
135             $trait = Moose::Util::resolve_metatrait_alias(Attribute => $trait)
136                   || $trait;
137
138             next if $class->does($trait);
139
140             push @traits, $trait;
141
142             # are there options?
143             push @traits, $traits->[$i++]
144                 if $traits->[$i] && ref($traits->[$i]);
145         }
146
147         if (@traits) {
148             my $anon_class = Moose::Meta::Class->create_anon_class(
149                 superclasses => [ $class ],
150                 roles        => [ @traits ],
151                 cache        => 1,
152             );
153
154             $class = $anon_class->name;
155         }
156     }
157
158     return ( wantarray ? ( $class, @traits ) : $class );
159 }
160
161 # ...
162
163 # method-generating options shouldn't be overridden
164 sub illegal_options_for_inheritance {
165     qw(reader writer accessor clearer predicate)
166 }
167
168 # NOTE/TODO
169 # This method *must* be able to handle
170 # Class::MOP::Attribute instances as
171 # well. Yes, I know that is wrong, but
172 # apparently we didn't realize it was
173 # doing that and now we have some code
174 # which is dependent on it. The real
175 # solution of course is to push this
176 # feature back up into Class::MOP::Attribute
177 # but I not right now, I am too lazy.
178 # However if you are reading this and
179 # looking for something to do,.. please
180 # be my guest.
181 # - stevan
182 sub clone_and_inherit_options {
183     my ($self, %options) = @_;
184
185     # NOTE:
186     # we may want to extends a Class::MOP::Attribute
187     # in which case we need to be able to use the
188     # core set of legal options that have always
189     # been here. But we allows Moose::Meta::Attribute
190     # instances to changes them.
191     # - SL
192     my @illegal_options = $self->can('illegal_options_for_inheritance')
193         ? $self->illegal_options_for_inheritance
194         : ();
195
196     my @found_illegal_options = grep { exists $options{$_} && exists $self->{$_} ? $_ : undef } @illegal_options;
197     (scalar @found_illegal_options == 0)
198         || $self->throw_error("Illegal inherited options => (" . (join ', ' => @found_illegal_options) . ")", data => \%options);
199
200     if ($options{isa}) {
201         my $type_constraint;
202         if (blessed($options{isa}) && $options{isa}->isa('Moose::Meta::TypeConstraint')) {
203             $type_constraint = $options{isa};
204         }
205         else {
206             $type_constraint = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options{isa});
207             (defined $type_constraint)
208                 || $self->throw_error("Could not find the type constraint '" . $options{isa} . "'", data => $options{isa});
209         }
210
211         $options{type_constraint} = $type_constraint;
212     }
213
214     if ($options{does}) {
215         my $type_constraint;
216         if (blessed($options{does}) && $options{does}->isa('Moose::Meta::TypeConstraint')) {
217             $type_constraint = $options{does};
218         }
219         else {
220             $type_constraint = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options{does});
221             (defined $type_constraint)
222                 || $self->throw_error("Could not find the type constraint '" . $options{does} . "'", data => $options{does});
223         }
224
225         $options{type_constraint} = $type_constraint;
226     }
227
228     # NOTE:
229     # this doesn't apply to Class::MOP::Attributes,
230     # so we can ignore it for them.
231     # - SL
232     if ($self->can('interpolate_class')) {
233         ( $options{metaclass}, my @traits ) = $self->interpolate_class(\%options);
234
235         my %seen;
236         my @all_traits = grep { $seen{$_}++ } @{ $self->applied_traits || [] }, @traits;
237         $options{traits} = \@all_traits if @all_traits;
238     }
239
240     # This method can be called on a CMOP::Attribute object, so we need to
241     # make sure we can call this method.
242     $self->_process_lazy_build_option( $self->name, \%options )
243         if $self->can('_process_lazy_build_option');
244
245     $self->clone(%options);
246 }
247
248 sub clone {
249     my ( $self, %params ) = @_;
250
251     my $class = delete $params{metaclass} || ref $self;
252
253     my ( @init, @non_init );
254
255     foreach my $attr ( grep { $_->has_value($self) } Class::MOP::class_of($self)->get_all_attributes ) {
256         push @{ $attr->has_init_arg ? \@init : \@non_init }, $attr;
257     }
258
259     my %new_params = ( ( map { $_->init_arg => $_->get_value($self) } @init ), %params );
260
261     my $name = delete $new_params{name};
262
263     my $clone = $class->new($name, %new_params, __hack_no_process_options => 1 );
264
265     foreach my $attr ( @non_init ) {
266         $attr->set_value($clone, $attr->get_value($self));
267     }
268
269     return $clone;
270 }
271
272 sub _process_options {
273     my ( $class, $name, $options ) = @_;
274
275     $class->_process_is_option( $name, $options );
276     $class->_process_isa_option( $name, $options );
277     $class->_process_does_option( $name, $options );
278     $class->_process_coerce_option( $name, $options );
279     $class->_process_trigger_option( $name, $options );
280     $class->_process_auto_deref_option( $name, $options );
281     $class->_process_lazy_build_option( $name, $options );
282     $class->_process_lazy_option( $name, $options );
283     $class->_process_required_option( $name, $options );
284 }
285
286 sub _process_is_option {
287     my ( $class, $name, $options ) = @_;
288
289     return unless $options->{is};
290
291     ### -------------------------
292     ## is => ro, writer => _foo    # turns into (reader => foo, writer => _foo) as before
293     ## is => rw, writer => _foo    # turns into (reader => foo, writer => _foo)
294     ## is => rw, accessor => _foo  # turns into (accessor => _foo)
295     ## is => ro, accessor => _foo  # error, accesor is rw
296     ### -------------------------
297
298     if ( $options->{is} eq 'ro' ) {
299         $class->throw_error(
300             "Cannot define an accessor name on a read-only attribute, accessors are read/write",
301             data => $options )
302             if exists $options->{accessor};
303         $options->{reader} ||= $name;
304     }
305     elsif ( $options->{is} eq 'rw' ) {
306         if ( $options->{writer} ) {
307             $options->{reader} ||= $name;
308         }
309         else {
310             $options->{accessor} ||= $name;
311         }
312     }
313     elsif ( $options->{is} eq 'bare' ) {
314         return;
315         # do nothing, but don't complain (later) about missing methods
316     }
317     else {
318         $class->throw_error( "I do not understand this option (is => "
319                 . $options->{is}
320                 . ") on attribute ($name)", data => $options->{is} );
321     }
322 }
323
324 sub _process_isa_option {
325     my ( $class, $name, $options ) = @_;
326
327     return unless exists $options->{isa};
328
329     if ( exists $options->{does} ) {
330         if ( try { $options->{isa}->can('does') } ) {
331             ( $options->{isa}->does( $options->{does} ) )
332                 || $class->throw_error(
333                 "Cannot have an isa option and a does option if the isa does not do the does on attribute ($name)",
334                 data => $options );
335         }
336         else {
337             $class->throw_error(
338                 "Cannot have an isa option which cannot ->does() on attribute ($name)",
339                 data => $options );
340         }
341     }
342
343     # allow for anon-subtypes here ...
344     if ( blessed( $options->{isa} )
345         && $options->{isa}->isa('Moose::Meta::TypeConstraint') ) {
346         $options->{type_constraint} = $options->{isa};
347     }
348     else {
349         $options->{type_constraint}
350             = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint(
351             $options->{isa} );
352     }
353 }
354
355 sub _process_does_option {
356     my ( $class, $name, $options ) = @_;
357
358     return unless exists $options->{does} && ! exists $options->{isa};
359
360     # allow for anon-subtypes here ...
361     if ( blessed( $options->{does} )
362         && $options->{does}->isa('Moose::Meta::TypeConstraint') ) {
363         $options->{type_constraint} = $options->{does};
364     }
365     else {
366         $options->{type_constraint}
367             = Moose::Util::TypeConstraints::find_or_create_does_type_constraint(
368             $options->{does} );
369     }
370 }
371
372 sub _process_coerce_option {
373     my ( $class, $name, $options ) = @_;
374
375     return unless $options->{coerce};
376
377     ( exists $options->{type_constraint} )
378         || $class->throw_error(
379         "You cannot have coercion without specifying a type constraint on attribute ($name)",
380         data => $options );
381
382     $class->throw_error(
383         "You cannot have a weak reference to a coerced value on attribute ($name)",
384         data => $options )
385         if $options->{weak_ref};
386
387     unless ( $options->{type_constraint}->has_coercion ) {
388         my $type = $options->{type_constraint}->name;
389
390         Moose::Deprecated::deprecated(
391             feature => 'coerce without coercion',
392             message =>
393                 "You cannot coerce an attribute ($name) unless its type ($type) has a coercion"
394         );
395     }
396 }
397
398 sub _process_trigger_option {
399     my ( $class, $name, $options ) = @_;
400
401     return unless exists $options->{trigger};
402
403     ( 'CODE' eq ref $options->{trigger} )
404         || $class->throw_error("Trigger must be a CODE ref on attribute ($name)", data => $options->{trigger});
405 }
406
407 sub _process_auto_deref_option {
408     my ( $class, $name, $options ) = @_;
409
410     return unless $options->{auto_deref};
411
412     ( exists $options->{type_constraint} )
413         || $class->throw_error(
414         "You cannot auto-dereference without specifying a type constraint on attribute ($name)",
415         data => $options );
416
417     ( $options->{type_constraint}->is_a_type_of('ArrayRef')
418       || $options->{type_constraint}->is_a_type_of('HashRef') )
419         || $class->throw_error(
420         "You cannot auto-dereference anything other than a ArrayRef or HashRef on attribute ($name)",
421         data => $options );
422 }
423
424 sub _process_lazy_build_option {
425     my ( $class, $name, $options ) = @_;
426
427     return unless $options->{lazy_build};
428
429     $class->throw_error(
430         "You can not use lazy_build and default for the same attribute ($name)",
431         data => $options )
432         if exists $options->{default};
433
434     $options->{lazy} = 1;
435     $options->{builder} ||= "_build_${name}";
436
437     if ( $name =~ /^_/ ) {
438         $options->{clearer}   ||= "_clear${name}";
439         $options->{predicate} ||= "_has${name}";
440     }
441     else {
442         $options->{clearer}   ||= "clear_${name}";
443         $options->{predicate} ||= "has_${name}";
444     }
445 }
446
447 sub _process_lazy_option {
448     my ( $class, $name, $options ) = @_;
449
450     return unless $options->{lazy};
451
452     ( exists $options->{default} || defined $options->{builder} )
453         || $class->throw_error(
454         "You cannot have a lazy attribute ($name) without specifying a default value for it",
455         data => $options );
456 }
457
458 sub _process_required_option {
459     my ( $class, $name, $options ) = @_;
460
461     if (
462         $options->{required}
463         && !(
464             ( !exists $options->{init_arg} || defined $options->{init_arg} )
465             || exists $options->{default}
466             || defined $options->{builder}
467         )
468         ) {
469         $class->throw_error(
470             "You cannot have a required attribute ($name) without a default, builder, or an init_arg",
471             data => $options );
472     }
473 }
474
475 sub initialize_instance_slot {
476     my ($self, $meta_instance, $instance, $params) = @_;
477     my $init_arg = $self->init_arg();
478     # try to fetch the init arg from the %params ...
479
480     my $val;
481     my $value_is_set;
482     if ( defined($init_arg) and exists $params->{$init_arg}) {
483         $val = $params->{$init_arg};
484         $value_is_set = 1;
485     }
486     else {
487         # skip it if it's lazy
488         return if $self->is_lazy;
489         # and die if it's required and doesn't have a default value
490         $self->throw_error("Attribute (" . $self->name . ") is required", object => $instance, data => $params)
491             if $self->is_required && !$self->has_default && !$self->has_builder;
492
493         # if nothing was in the %params, we can use the
494         # attribute's default value (if it has one)
495         if ($self->has_default) {
496             $val = $self->default($instance);
497             $value_is_set = 1;
498         }
499         elsif ($self->has_builder) {
500             $val = $self->_call_builder($instance);
501             $value_is_set = 1;
502         }
503     }
504
505     return unless $value_is_set;
506
507     $val = $self->_coerce_and_verify( $val, $instance );
508
509     $self->set_initial_value($instance, $val);
510
511     if ( ref $val && $self->is_weak_ref ) {
512         $self->_weaken_value($instance);
513     }
514 }
515
516 sub _call_builder {
517     my ( $self, $instance ) = @_;
518
519     my $builder = $self->builder();
520
521     return $instance->$builder()
522         if $instance->can( $self->builder );
523
524     $self->throw_error(  blessed($instance)
525             . " does not support builder method '"
526             . $self->builder
527             . "' for attribute '"
528             . $self->name
529             . "'",
530             object => $instance,
531      );
532 }
533
534 ## Slot management
535
536 sub _make_initializer_writer_callback {
537     my $self = shift;
538     my ($meta_instance, $instance, $slot_name) = @_;
539     my $old_callback = $self->SUPER::_make_initializer_writer_callback(@_);
540     return sub {
541         $old_callback->($self->_coerce_and_verify($_[0], $instance));
542     };
543 }
544
545 sub set_value {
546     my ($self, $instance, @args) = @_;
547     my $value = $args[0];
548
549     my $attr_name = quotemeta($self->name);
550
551     if ($self->is_required and not @args) {
552         $self->throw_error("Attribute ($attr_name) is required", object => $instance);
553     }
554
555     $value = $self->_coerce_and_verify( $value, $instance );
556
557     my @old;
558     if ( $self->has_trigger && $self->has_value($instance) ) {
559         @old = $self->get_value($instance, 'for trigger');
560     }
561
562     $self->SUPER::set_value($instance, $value);
563
564     if ( ref $value && $self->is_weak_ref ) {
565         $self->_weaken_value($instance);
566     }
567
568     if ($self->has_trigger) {
569         $self->trigger->($instance, $value, @old);
570     }
571 }
572
573 sub _inline_set_value {
574     my $self = shift;
575     my ($instance, $value, $tc, $coercion, $tc_obj, $for_constructor) = @_;
576
577     my $old     = '@old';
578     my $copy    = '$val';
579     $tc       ||= '$type_constraint';
580     $coercion ||= '$type_coercion';
581     $tc_obj   ||= '$type_constraint_obj';
582
583     my @code;
584     if ($self->_writer_value_needs_copy) {
585         push @code, $self->_inline_copy_value($value, $copy);
586         $value = $copy;
587     }
588
589     # constructors already handle required checks
590     push @code, $self->_inline_check_required
591         unless $for_constructor;
592
593     push @code, $self->_inline_tc_code($value, $tc, $coercion, $tc_obj);
594
595     # constructors do triggers all at once at the end
596     push @code, $self->_inline_get_old_value_for_trigger($instance, $old)
597         unless $for_constructor;
598
599     push @code, (
600         $self->SUPER::_inline_set_value($instance, $value),
601         $self->_inline_weaken_value($instance, $value),
602     );
603
604     # constructors do triggers all at once at the end
605     push @code, $self->_inline_trigger($instance, $value, $old)
606         unless $for_constructor;
607
608     return @code;
609 }
610
611 sub _writer_value_needs_copy {
612     my $self = shift;
613     return $self->should_coerce;
614 }
615
616 sub _inline_copy_value {
617     my $self = shift;
618     my ($value, $copy) = @_;
619
620     return 'my ' . $copy . ' = ' . $value . ';'
621 }
622
623 sub _inline_check_required {
624     my $self = shift;
625
626     return unless $self->is_required;
627
628     my $attr_name = quotemeta($self->name);
629
630     return (
631         'if (@_ < 2) {',
632             $self->_inline_throw_error(
633                 '"Attribute (' . $attr_name . ') is required, so cannot '
634               . 'be set to undef"' # defined $_[1] is not good enough
635             ) . ';',
636         '}',
637     );
638 }
639
640 sub _inline_tc_code {
641     my $self = shift;
642     my ($value, $tc, $coercion, $tc_obj, $is_lazy) = @_;
643     return (
644         $self->_inline_check_coercion(
645             $value, $tc, $coercion, $is_lazy,
646         ),
647         $self->_inline_check_constraint(
648             $value, $tc, $tc_obj, $is_lazy,
649         ),
650     );
651 }
652
653 sub _inline_check_coercion {
654     my $self = shift;
655     my ($value, $tc, $coercion) = @_;
656
657     return unless $self->should_coerce && $self->type_constraint->has_coercion;
658
659     if ( $self->type_constraint->can_be_inlined ) {
660         return (
661             'if (! (' . $self->type_constraint->_inline_check($value) . ')) {',
662                 $value . ' = ' . $coercion . '->(' . $value . ');',
663             '}',
664         );
665     }
666     else {
667         return (
668             'if (!' . $tc . '->(' . $value . ')) {',
669                 $value . ' = ' . $coercion . '->(' . $value . ');',
670             '}',
671         );
672     }
673 }
674
675 sub _inline_check_constraint {
676     my $self = shift;
677     my ($value, $tc, $tc_obj) = @_;
678
679     return unless $self->has_type_constraint;
680
681     my $attr_name = quotemeta($self->name);
682
683     if ( $self->type_constraint->can_be_inlined ) {
684         return (
685             'if (! (' . $self->type_constraint->_inline_check($value) . ')) {',
686                 $self->_inline_throw_error(
687                     '"Attribute (' . $attr_name . ') does not pass the type '
688                   . 'constraint because: " . '
689                   . $tc_obj . '->get_message(' . $value . ')',
690                     'data => ' . $value
691                 ) . ';',
692             '}',
693         );
694     }
695     else {
696         return (
697             'if (!' . $tc . '->(' . $value . ')) {',
698                 $self->_inline_throw_error(
699                     '"Attribute (' . $attr_name . ') does not pass the type '
700                   . 'constraint because: " . '
701                   . $tc_obj . '->get_message(' . $value . ')',
702                     'data => ' . $value
703                 ) . ';',
704             '}',
705         );
706     }
707 }
708
709 sub _inline_get_old_value_for_trigger {
710     my $self = shift;
711     my ($instance, $old) = @_;
712
713     return unless $self->has_trigger;
714
715     return (
716         'my ' . $old . ' = ' . $self->_inline_instance_has($instance),
717             '? ' . $self->_inline_instance_get($instance),
718             ': ();',
719     );
720 }
721
722 sub _inline_weaken_value {
723     my $self = shift;
724     my ($instance, $value) = @_;
725
726     return unless $self->is_weak_ref;
727
728     my $mi = $self->associated_class->get_meta_instance;
729     return (
730         $mi->inline_weaken_slot_value($instance, $self->name, $value),
731             'if ref ' . $value . ';',
732     );
733 }
734
735 sub _inline_trigger {
736     my $self = shift;
737     my ($instance, $value, $old) = @_;
738
739     return unless $self->has_trigger;
740
741     return '$trigger->(' . $instance . ', ' . $value . ', ' . $old . ');';
742 }
743
744 sub _weaken_value {
745     my ( $self, $instance ) = @_;
746
747     my $meta_instance = Class::MOP::Class->initialize( blessed($instance) )
748         ->get_meta_instance;
749
750     $meta_instance->weaken_slot_value( $instance, $self->name );
751 }
752
753 sub get_value {
754     my ($self, $instance, $for_trigger) = @_;
755
756     if ($self->is_lazy) {
757         unless ($self->has_value($instance)) {
758             my $value;
759             if ($self->has_default) {
760                 $value = $self->default($instance);
761             } elsif ( $self->has_builder ) {
762                 $value = $self->_call_builder($instance);
763             }
764
765             $value = $self->_coerce_and_verify( $value, $instance );
766
767             $self->set_initial_value($instance, $value);
768         }
769     }
770
771     if ( $self->should_auto_deref && ! $for_trigger ) {
772
773         my $type_constraint = $self->type_constraint;
774
775         if ($type_constraint->is_a_type_of('ArrayRef')) {
776             my $rv = $self->SUPER::get_value($instance);
777             return unless defined $rv;
778             return wantarray ? @{ $rv } : $rv;
779         }
780         elsif ($type_constraint->is_a_type_of('HashRef')) {
781             my $rv = $self->SUPER::get_value($instance);
782             return unless defined $rv;
783             return wantarray ? %{ $rv } : $rv;
784         }
785         else {
786             $self->throw_error("Can not auto de-reference the type constraint '" . $type_constraint->name . "'", object => $instance, type_constraint => $type_constraint);
787         }
788
789     }
790     else {
791
792         return $self->SUPER::get_value($instance);
793     }
794 }
795
796 sub _inline_get_value {
797     my $self = shift;
798     my ($instance, $tc, $coercion, $tc_obj) = @_;
799
800     my $slot_access = $self->_inline_instance_get($instance);
801     $tc           ||= '$type_constraint';
802     $coercion     ||= '$type_coercion';
803     $tc_obj       ||= '$type_constraint_obj';
804
805     return (
806         $self->_inline_check_lazy($instance, $tc, $coercion, $tc_obj),
807         $self->_inline_return_auto_deref($slot_access),
808     );
809 }
810
811 sub _inline_check_lazy {
812     my $self = shift;
813     my ($instance, $tc, $coercion, $tc_obj) = @_;
814
815     return unless $self->is_lazy;
816
817     my $slot_exists = $self->_inline_instance_has($instance);
818
819     return (
820         'if (!' . $slot_exists . ') {',
821             $self->_inline_init_from_default($instance, '$default', $tc, $coercion, $tc_obj, 'lazy'),
822         '}',
823     );
824 }
825
826 sub _inline_init_from_default {
827     my $self = shift;
828     my ($instance, $default, $tc, $coercion, $tc_obj, $for_lazy) = @_;
829
830     if (!($self->has_default || $self->has_builder)) {
831         $self->throw_error(
832             'You cannot have a lazy attribute '
833           . '(' . $self->name . ') '
834           . 'without specifying a default value for it',
835             attr => $self,
836         );
837     }
838
839     return (
840         $self->_inline_generate_default($instance, $default),
841         # intentionally not using _inline_tc_code, since that can be overridden
842         # to do things like possibly only do member tc checks, which isn't
843         # appropriate for checking the result of a default
844         $self->has_type_constraint
845             ? ($self->_inline_check_coercion($default, $tc, $coercion, $for_lazy),
846                $self->_inline_check_constraint($default, $tc, $tc_obj, $for_lazy))
847             : (),
848         $self->_inline_init_slot($instance, $default),
849     );
850 }
851
852 sub _inline_generate_default {
853     my $self = shift;
854     my ($instance, $default) = @_;
855
856     if ($self->has_default) {
857         my $source = 'my ' . $default . ' = $default';
858         $source .= '->(' . $instance . ')'
859             if $self->is_default_a_coderef;
860         return $source . ';';
861     }
862     elsif ($self->has_builder) {
863         my $builder = B::perlstring($self->builder);
864         my $builder_str = quotemeta($self->builder);
865         my $attr_name_str = quotemeta($self->name);
866         return (
867             'my ' . $default . ';',
868             'if (my $builder = ' . $instance . '->can(' . $builder . ')) {',
869                 $default . ' = ' . $instance . '->$builder;',
870             '}',
871             'else {',
872                 'my $class = ref(' . $instance . ') || ' . $instance . ';',
873                 $self->_inline_throw_error(
874                     '"$class does not support builder method '
875                   . '\'' . $builder_str . '\' for attribute '
876                   . '\'' . $attr_name_str . '\'"'
877                 ) . ';',
878             '}',
879         );
880     }
881     else {
882         $self->throw_error(
883             "Can't generate a default for " . $self->name
884           . " since no default or builder was specified"
885         );
886     }
887 }
888
889 sub _inline_init_slot {
890     my $self = shift;
891     my ($inv, $value) = @_;
892
893     if ($self->has_initializer) {
894         return '$attr->set_initial_value(' . $inv . ', ' . $value . ');';
895     }
896     else {
897         return $self->_inline_instance_set($inv, $value) . ';';
898     }
899 }
900
901 sub _inline_return_auto_deref {
902     my $self = shift;
903
904     return 'return ' . $self->_auto_deref(@_) . ';';
905 }
906
907 sub _auto_deref {
908     my $self = shift;
909     my ($ref_value) = @_;
910
911     return $ref_value unless $self->should_auto_deref;
912
913     my $type_constraint = $self->type_constraint;
914
915     my $sigil;
916     if ($type_constraint->is_a_type_of('ArrayRef')) {
917         $sigil = '@';
918     }
919     elsif ($type_constraint->is_a_type_of('HashRef')) {
920         $sigil = '%';
921     }
922     else {
923         $self->throw_error(
924             'Can not auto de-reference the type constraint \''
925           . $type_constraint->name
926           . '\'',
927             type_constraint => $type_constraint,
928         );
929     }
930
931     return 'wantarray '
932              . '? ' . $sigil . '{ (' . $ref_value . ') || return } '
933              . ': (' . $ref_value . ')';
934 }
935
936 ## installing accessors
937
938 sub accessor_metaclass { 'Moose::Meta::Method::Accessor' }
939
940 sub install_accessors {
941     my $self = shift;
942     $self->SUPER::install_accessors(@_);
943     $self->install_delegation if $self->has_handles;
944     return;
945 }
946
947 sub _check_associated_methods {
948     my $self = shift;
949     unless (
950         @{ $self->associated_methods }
951         || ($self->_is_metadata || '') eq 'bare'
952     ) {
953         Carp::cluck(
954             'Attribute (' . $self->name . ') of class '
955             . $self->associated_class->name
956             . ' has no associated methods'
957             . ' (did you mean to provide an "is" argument?)'
958             . "\n"
959         )
960     }
961 }
962
963 sub _process_accessors {
964     my $self = shift;
965     my ($type, $accessor, $generate_as_inline_methods) = @_;
966
967     $accessor = ( keys %$accessor )[0] if ( ref($accessor) || '' ) eq 'HASH';
968     my $method = $self->associated_class->get_method($accessor);
969
970     if (   $method
971         && $method->isa('Class::MOP::Method::Accessor')
972         && $method->associated_attribute->name ne $self->name ) {
973
974         my $other_attr_name = $method->associated_attribute->name;
975         my $name            = $self->name;
976
977         Carp::cluck(
978             "You are overwriting an accessor ($accessor) for the $other_attr_name attribute"
979                 . " with a new accessor method for the $name attribute" );
980     }
981
982     if (
983            $method
984         && !$method->isa('Class::MOP::Method::Accessor')
985         && (  !$self->definition_context
986             || $method->package_name eq $self->definition_context->{package} )
987         ) {
988
989         Carp::cluck(
990             "You are overwriting a locally defined method ($accessor) with "
991                 . "an accessor" );
992     }
993
994     if (  !$self->associated_class->has_method($accessor)
995         && $self->associated_class->has_package_symbol( '&' . $accessor ) ) {
996
997         Carp::cluck(
998             "You are overwriting a locally defined function ($accessor) with "
999                 . "an accessor" );
1000     }
1001
1002     $self->SUPER::_process_accessors(@_);
1003 }
1004
1005 sub remove_accessors {
1006     my $self = shift;
1007     $self->SUPER::remove_accessors(@_);
1008     $self->remove_delegation if $self->has_handles;
1009     return;
1010 }
1011
1012 sub install_delegation {
1013     my $self = shift;
1014
1015     # NOTE:
1016     # Here we canonicalize the 'handles' option
1017     # this will sort out any details and always
1018     # return an hash of methods which we want
1019     # to delagate to, see that method for details
1020     my %handles = $self->_canonicalize_handles;
1021
1022
1023     # install the delegation ...
1024     my $associated_class = $self->associated_class;
1025     foreach my $handle (keys %handles) {
1026         my $method_to_call = $handles{$handle};
1027         my $class_name = $associated_class->name;
1028         my $name = "${class_name}::${handle}";
1029
1030             (!$associated_class->has_method($handle))
1031                 || $self->throw_error("You cannot overwrite a locally defined method ($handle) with a delegation", method_name => $handle);
1032
1033         # NOTE:
1034         # handles is not allowed to delegate
1035         # any of these methods, as they will
1036         # override the ones in your class, which
1037         # is almost certainly not what you want.
1038
1039         # FIXME warn when $handle was explicitly specified, but not if the source is a regex or something
1040         #cluck("Not delegating method '$handle' because it is a core method") and
1041         next if $class_name->isa("Moose::Object") and $handle =~ /^BUILD|DEMOLISH$/ || Moose::Object->can($handle);
1042
1043         my $method = $self->_make_delegation_method($handle, $method_to_call);
1044
1045         $self->associated_class->add_method($method->name, $method);
1046         $self->associate_method($method);
1047     }
1048 }
1049
1050 sub remove_delegation {
1051     my $self = shift;
1052     my %handles = $self->_canonicalize_handles;
1053     my $associated_class = $self->associated_class;
1054     foreach my $handle (keys %handles) {
1055         next unless any { $handle eq $_ }
1056                     map { $_->name }
1057                     @{ $self->associated_methods };
1058         $self->associated_class->remove_method($handle);
1059     }
1060 }
1061
1062 # private methods to help delegation ...
1063
1064 sub _canonicalize_handles {
1065     my $self    = shift;
1066     my $handles = $self->handles;
1067     if (my $handle_type = ref($handles)) {
1068         if ($handle_type eq 'HASH') {
1069             return %{$handles};
1070         }
1071         elsif ($handle_type eq 'ARRAY') {
1072             return map { $_ => $_ } @{$handles};
1073         }
1074         elsif ($handle_type eq 'Regexp') {
1075             ($self->has_type_constraint)
1076                 || $self->throw_error("Cannot delegate methods based on a Regexp without a type constraint (isa)", data => $handles);
1077             return map  { ($_ => $_) }
1078                    grep { /$handles/ } $self->_get_delegate_method_list;
1079         }
1080         elsif ($handle_type eq 'CODE') {
1081             return $handles->($self, $self->_find_delegate_metaclass);
1082         }
1083         elsif (blessed($handles) && $handles->isa('Moose::Meta::TypeConstraint::DuckType')) {
1084             return map { $_ => $_ } @{ $handles->methods };
1085         }
1086         elsif (blessed($handles) && $handles->isa('Moose::Meta::TypeConstraint::Role')) {
1087             $handles = $handles->role;
1088         }
1089         else {
1090             $self->throw_error("Unable to canonicalize the 'handles' option with $handles", data => $handles);
1091         }
1092     }
1093
1094     Class::MOP::load_class($handles);
1095     my $role_meta = Class::MOP::class_of($handles);
1096
1097     (blessed $role_meta && $role_meta->isa('Moose::Meta::Role'))
1098         || $self->throw_error("Unable to canonicalize the 'handles' option with $handles because its metaclass is not a Moose::Meta::Role", data => $handles);
1099
1100     return map { $_ => $_ }
1101         map { $_->name }
1102         grep { !$_->isa('Class::MOP::Method::Meta') } (
1103         $role_meta->_get_local_methods,
1104         $role_meta->get_required_method_list,
1105         );
1106 }
1107
1108 sub _get_delegate_method_list {
1109     my $self = shift;
1110     my $meta = $self->_find_delegate_metaclass;
1111     if ($meta->isa('Class::MOP::Class')) {
1112         return map  { $_->name }  # NOTE: !never! delegate &meta
1113                grep { $_->package_name ne 'Moose::Object' && !$_->isa('Class::MOP::Method::Meta') }
1114                     $meta->get_all_methods;
1115     }
1116     elsif ($meta->isa('Moose::Meta::Role')) {
1117         return $meta->get_method_list;
1118     }
1119     else {
1120         $self->throw_error("Unable to recognize the delegate metaclass '$meta'", data => $meta);
1121     }
1122 }
1123
1124 sub _find_delegate_metaclass {
1125     my $self = shift;
1126     if (my $class = $self->_isa_metadata) {
1127         unless ( Class::MOP::is_class_loaded($class) ) {
1128             $self->throw_error(
1129                 sprintf(
1130                     'The %s attribute is trying to delegate to a class which has not been loaded - %s',
1131                     $self->name, $class
1132                 )
1133             );
1134         }
1135         # we might be dealing with a non-Moose class,
1136         # and need to make our own metaclass. if there's
1137         # already a metaclass, it will be returned
1138         return Class::MOP::Class->initialize($class);
1139     }
1140     elsif (my $role = $self->_does_metadata) {
1141         unless ( Class::MOP::is_class_loaded($class) ) {
1142             $self->throw_error(
1143                 sprintf(
1144                     'The %s attribute is trying to delegate to a role which has not been loaded - %s',
1145                     $self->name, $role
1146                 )
1147             );
1148         }
1149
1150         return Class::MOP::class_of($role);
1151     }
1152     else {
1153         $self->throw_error("Cannot find delegate metaclass for attribute " . $self->name);
1154     }
1155 }
1156
1157 sub delegation_metaclass { 'Moose::Meta::Method::Delegation' }
1158
1159 sub _make_delegation_method {
1160     my ( $self, $handle_name, $method_to_call ) = @_;
1161
1162     my @curried_arguments;
1163
1164     ($method_to_call, @curried_arguments) = @$method_to_call
1165         if 'ARRAY' eq ref($method_to_call);
1166
1167     return $self->delegation_metaclass->new(
1168         name               => $handle_name,
1169         package_name       => $self->associated_class->name,
1170         attribute          => $self,
1171         delegate_to_method => $method_to_call,
1172         curried_arguments  => \@curried_arguments,
1173     );
1174 }
1175
1176 sub _coerce_and_verify {
1177     my $self     = shift;
1178     my $val      = shift;
1179     my $instance = shift;
1180
1181     return $val unless $self->has_type_constraint;
1182
1183     $val = $self->type_constraint->coerce($val)
1184         if $self->should_coerce && $self->type_constraint->has_coercion;
1185
1186     $self->verify_against_type_constraint($val, instance => $instance);
1187
1188     return $val;
1189 }
1190
1191 sub verify_against_type_constraint {
1192     my $self = shift;
1193     my $val  = shift;
1194
1195     return 1 if !$self->has_type_constraint;
1196
1197     my $type_constraint = $self->type_constraint;
1198
1199     $type_constraint->check($val)
1200         || $self->throw_error("Attribute ("
1201                  . $self->name
1202                  . ") does not pass the type constraint because: "
1203                  . $type_constraint->get_message($val), data => $val, @_);
1204 }
1205
1206 package Moose::Meta::Attribute::Custom::Moose;
1207 sub register_implementation { 'Moose::Meta::Attribute' }
1208
1209 1;
1210
1211 # ABSTRACT: The Moose attribute metaclass
1212
1213 __END__
1214
1215 =pod
1216
1217 =head1 DESCRIPTION
1218
1219 This class is a subclass of L<Class::MOP::Attribute> that provides
1220 additional Moose-specific functionality.
1221
1222 To really understand this class, you will need to start with the
1223 L<Class::MOP::Attribute> documentation. This class can be understood
1224 as a set of additional features on top of the basic feature provided
1225 by that parent class.
1226
1227 =head1 INHERITANCE
1228
1229 C<Moose::Meta::Attribute> is a subclass of L<Class::MOP::Attribute>.
1230
1231 =head1 METHODS
1232
1233 Many of the documented below override methods in
1234 L<Class::MOP::Attribute> and add Moose specific features.
1235
1236 =head2 Creation
1237
1238 =over 4
1239
1240 =item B<< Moose::Meta::Attribute->new(%options) >>
1241
1242 This method overrides the L<Class::MOP::Attribute> constructor.
1243
1244 Many of the options below are described in more detail in the
1245 L<Moose::Manual::Attributes> document.
1246
1247 It adds the following options to the constructor:
1248
1249 =over 8
1250
1251 =item * is => 'ro', 'rw', 'bare'
1252
1253 This provides a shorthand for specifying the C<reader>, C<writer>, or
1254 C<accessor> names. If the attribute is read-only ('ro') then it will
1255 have a C<reader> method with the same attribute as the name.
1256
1257 If it is read-write ('rw') then it will have an C<accessor> method
1258 with the same name. If you provide an explicit C<writer> for a
1259 read-write attribute, then you will have a C<reader> with the same
1260 name as the attribute, and a C<writer> with the name you provided.
1261
1262 Use 'bare' when you are deliberately not installing any methods
1263 (accessor, reader, etc.) associated with this attribute; otherwise,
1264 Moose will issue a deprecation warning when this attribute is added to a
1265 metaclass.
1266
1267 =item * isa => $type
1268
1269 This option accepts a type. The type can be a string, which should be
1270 a type name. If the type name is unknown, it is assumed to be a class
1271 name.
1272
1273 This option can also accept a L<Moose::Meta::TypeConstraint> object.
1274
1275 If you I<also> provide a C<does> option, then your C<isa> option must
1276 be a class name, and that class must do the role specified with
1277 C<does>.
1278
1279 =item * does => $role
1280
1281 This is short-hand for saying that the attribute's type must be an
1282 object which does the named role.
1283
1284 =item * coerce => $bool
1285
1286 This option is only valid for objects with a type constraint
1287 (C<isa>) that defined a coercion. If this is true, then coercions will be applied whenever
1288 this attribute is set.
1289
1290 You can make both this and the C<weak_ref> option true.
1291
1292 =item * trigger => $sub
1293
1294 This option accepts a subroutine reference, which will be called after
1295 the attribute is set.
1296
1297 =item * required => $bool
1298
1299 An attribute which is required must be provided to the constructor. An
1300 attribute which is required can also have a C<default> or C<builder>,
1301 which will satisfy its required-ness.
1302
1303 A required attribute must have a C<default>, C<builder> or a
1304 non-C<undef> C<init_arg>
1305
1306 =item * lazy => $bool
1307
1308 A lazy attribute must have a C<default> or C<builder>. When an
1309 attribute is lazy, the default value will not be calculated until the
1310 attribute is read.
1311
1312 =item * weak_ref => $bool
1313
1314 If this is true, the attribute's value will be stored as a weak
1315 reference.
1316
1317 =item * auto_deref => $bool
1318
1319 If this is true, then the reader will dereference the value when it is
1320 called. The attribute must have a type constraint which defines the
1321 attribute as an array or hash reference.
1322
1323 =item * lazy_build => $bool
1324
1325 Setting this to true makes the attribute lazy and provides a number of
1326 default methods.
1327
1328   has 'size' => (
1329       is         => 'ro',
1330       lazy_build => 1,
1331   );
1332
1333 is equivalent to this:
1334
1335   has 'size' => (
1336       is        => 'ro',
1337       lazy      => 1,
1338       builder   => '_build_size',
1339       clearer   => 'clear_size',
1340       predicate => 'has_size',
1341   );
1342
1343
1344 If your attribute name starts with an underscore (C<_>), then the clearer
1345 and predicate will as well:
1346
1347   has '_size' => (
1348       is         => 'ro',
1349       lazy_build => 1,
1350   );
1351
1352 becomes:
1353
1354   has '_size' => (
1355       is        => 'ro',
1356       lazy      => 1,
1357       builder   => '_build__size',
1358       clearer   => '_clear_size',
1359       predicate => '_has_size',
1360   );
1361
1362 Note the doubled underscore in the builder name. Internally, Moose
1363 simply prepends the attribute name with "_build_" to come up with the
1364 builder name.
1365
1366 =item * documentation
1367
1368 An arbitrary string that can be retrieved later by calling C<<
1369 $attr->documentation >>.
1370
1371 =back
1372
1373 =item B<< $attr->clone(%options) >>
1374
1375 This creates a new attribute based on attribute being cloned. You must
1376 supply a C<name> option to provide a new name for the attribute.
1377
1378 The C<%options> can only specify options handled by
1379 L<Class::MOP::Attribute>.
1380
1381 =back
1382
1383 =head2 Value management
1384
1385 =over 4
1386
1387 =item B<< $attr->initialize_instance_slot($meta_instance, $instance, $params) >>
1388
1389 This method is used internally to initialize the attribute's slot in
1390 the object C<$instance>.
1391
1392 This overrides the L<Class::MOP::Attribute> method to handle lazy
1393 attributes, weak references, and type constraints.
1394
1395 =item B<get_value>
1396
1397 =item B<set_value>
1398
1399   eval { $point->meta->get_attribute('x')->set_value($point, 'forty-two') };
1400   if($@) {
1401     print "Oops: $@\n";
1402   }
1403
1404 I<Attribute (x) does not pass the type constraint (Int) with 'forty-two'>
1405
1406 Before setting the value, a check is made on the type constraint of
1407 the attribute, if it has one, to see if the value passes it. If the
1408 value fails to pass, the set operation dies with a L</throw_error>.
1409
1410 Any coercion to convert values is done before checking the type constraint.
1411
1412 To check a value against a type constraint before setting it, fetch the
1413 attribute instance using L<Class::MOP::Class/find_attribute_by_name>,
1414 fetch the type_constraint from the attribute using L<Moose::Meta::Attribute/type_constraint>
1415 and call L<Moose::Meta::TypeConstraint/check>. See L<Moose::Cookbook::Basics::Recipe4>
1416 for an example.
1417
1418 =back
1419
1420 =head2 Attribute Accessor generation
1421
1422 =over 4
1423
1424 =item B<< $attr->install_accessors >>
1425
1426 This method overrides the parent to also install delegation methods.
1427
1428 If, after installing all methods, the attribute object has no associated
1429 methods, it throws an error unless C<< is => 'bare' >> was passed to the
1430 attribute constructor.  (Trying to add an attribute that has no associated
1431 methods is almost always an error.)
1432
1433 =item B<< $attr->remove_accessors >>
1434
1435 This method overrides the parent to also remove delegation methods.
1436
1437 =item B<< $attr->inline_set($instance_var, $value_var) >>
1438
1439 This method return a code snippet suitable for inlining the relevant
1440 operation. It expect strings containing variable names to be used in the
1441 inlining, like C<'$self'> or C<'$_[1]'>.
1442
1443 =item B<< $attr->install_delegation >>
1444
1445 This method adds its delegation methods to the attribute's associated
1446 class, if it has any to add.
1447
1448 =item B<< $attr->remove_delegation >>
1449
1450 This method remove its delegation methods from the attribute's
1451 associated class.
1452
1453 =item B<< $attr->accessor_metaclass >>
1454
1455 Returns the accessor metaclass name, which defaults to
1456 L<Moose::Meta::Method::Accessor>.
1457
1458 =item B<< $attr->delegation_metaclass >>
1459
1460 Returns the delegation metaclass name, which defaults to
1461 L<Moose::Meta::Method::Delegation>.
1462
1463 =back
1464
1465 =head2 Additional Moose features
1466
1467 These methods are not found in the superclass. They support features
1468 provided by Moose.
1469
1470 =over 4
1471
1472 =item B<< $attr->does($role) >>
1473
1474 This indicates whether the I<attribute itself> does the given
1475 role. The role can be given as a full class name, or as a resolvable
1476 trait name.
1477
1478 Note that this checks the attribute itself, not its type constraint,
1479 so it is checking the attribute's metaclass and any traits applied to
1480 the attribute.
1481
1482 =item B<< Moose::Meta::Class->interpolate_class_and_new($name, %options) >>
1483
1484 This is an alternate constructor that handles the C<metaclass> and
1485 C<traits> options.
1486
1487 Effectively, this method is a factory that finds or creates the
1488 appropriate class for the given C<metaclass> and/or C<traits>.
1489
1490 Once it has the appropriate class, it will call C<< $class->new($name,
1491 %options) >> on that class.
1492
1493 =item B<< $attr->clone_and_inherit_options(%options) >>
1494
1495 This method supports the C<has '+foo'> feature. It does various bits
1496 of processing on the supplied C<%options> before ultimately calling
1497 the C<clone> method.
1498
1499 One of its main tasks is to make sure that the C<%options> provided
1500 does not include the options returned by the
1501 C<illegal_options_for_inheritance> method.
1502
1503 =item B<< $attr->illegal_options_for_inheritance >>
1504
1505 This returns a blacklist of options that can not be overridden in a
1506 subclass's attribute definition.
1507
1508 This exists to allow a custom metaclass to change or add to the list
1509 of options which can not be changed.
1510
1511 =item B<< $attr->type_constraint >>
1512
1513 Returns the L<Moose::Meta::TypeConstraint> object for this attribute,
1514 if it has one.
1515
1516 =item B<< $attr->has_type_constraint >>
1517
1518 Returns true if this attribute has a type constraint.
1519
1520 =item B<< $attr->verify_against_type_constraint($value) >>
1521
1522 Given a value, this method returns true if the value is valid for the
1523 attribute's type constraint. If the value is not valid, it throws an
1524 error.
1525
1526 =item B<< $attr->handles >>
1527
1528 This returns the value of the C<handles> option passed to the
1529 constructor.
1530
1531 =item B<< $attr->has_handles >>
1532
1533 Returns true if this attribute performs delegation.
1534
1535 =item B<< $attr->is_weak_ref >>
1536
1537 Returns true if this attribute stores its value as a weak reference.
1538
1539 =item B<< $attr->is_required >>
1540
1541 Returns true if this attribute is required to have a value.
1542
1543 =item B<< $attr->is_lazy >>
1544
1545 Returns true if this attribute is lazy.
1546
1547 =item B<< $attr->is_lazy_build >>
1548
1549 Returns true if the C<lazy_build> option was true when passed to the
1550 constructor.
1551
1552 =item B<< $attr->should_coerce >>
1553
1554 Returns true if the C<coerce> option passed to the constructor was
1555 true.
1556
1557 =item B<< $attr->should_auto_deref >>
1558
1559 Returns true if the C<auto_deref> option passed to the constructor was
1560 true.
1561
1562 =item B<< $attr->trigger >>
1563
1564 This is the subroutine reference that was in the C<trigger> option
1565 passed to the constructor, if any.
1566
1567 =item B<< $attr->has_trigger >>
1568
1569 Returns true if this attribute has a trigger set.
1570
1571 =item B<< $attr->documentation >>
1572
1573 Returns the value that was in the C<documentation> option passed to
1574 the constructor, if any.
1575
1576 =item B<< $attr->has_documentation >>
1577
1578 Returns true if this attribute has any documentation.
1579
1580 =item B<< $attr->applied_traits >>
1581
1582 This returns an array reference of all the traits which were applied
1583 to this attribute. If none were applied, this returns C<undef>.
1584
1585 =item B<< $attr->has_applied_traits >>
1586
1587 Returns true if this attribute has any traits applied.
1588
1589 =back
1590
1591 =head1 BUGS
1592
1593 See L<Moose/BUGS> for details on reporting bugs.
1594
1595 =cut