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