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