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