Revert "Explicitly pass message"
[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                     'roles => ["Moose::Exception::TypeConstraint"]',
696                     'attribute_name => ' . $self->name,
697                     'type_name => ' . $self->type_constraint->name,
698                     'value => ' . $value,
699                 ) . ';',
700             '}',
701         );
702     }
703     else {
704         return (
705             'if (!' . $tc . '->(' . $value . ')) {',
706                 $self->_inline_throw_error(
707                     '"Attribute (' . $attr_name . ') does not pass the type '
708                   . 'constraint because: " . '
709                   . 'do { local $_ = ' . $value . '; '
710                       . $message . '->(' . $value . ')'
711                   . '}',
712                     'roles => ["Moose::Exception::TypeConstraint"]',
713                     'attribute_name => ' . $self->name,
714                     'type_name => ' . $self->type_constraint->name,
715                     'value => ' . $value,
716                 ) . ';',
717             '}',
718         );
719     }
720 }
721
722 sub _inline_get_old_value_for_trigger {
723     my $self = shift;
724     my ($instance, $old) = @_;
725
726     return unless $self->has_trigger;
727
728     return (
729         'my ' . $old . ' = ' . $self->_inline_instance_has($instance),
730             '? ' . $self->_inline_instance_get($instance),
731             ': ();',
732     );
733 }
734
735 sub _inline_weaken_value {
736     my $self = shift;
737     my ($instance, $value) = @_;
738
739     return unless $self->is_weak_ref;
740
741     my $mi = $self->associated_class->get_meta_instance;
742     return (
743         $mi->inline_weaken_slot_value($instance, $self->name),
744             'if ref ' . $value . ';',
745     );
746 }
747
748 sub _inline_trigger {
749     my $self = shift;
750     my ($instance, $value, $old) = @_;
751
752     return unless $self->has_trigger;
753
754     return '$trigger->(' . $instance . ', ' . $value . ', ' . $old . ');';
755 }
756
757 sub _eval_environment {
758     my $self = shift;
759
760     my $env = { };
761
762     $env->{'$trigger'} = \($self->trigger)
763         if $self->has_trigger;
764     $env->{'$attr_default'} = \($self->default)
765         if $self->has_default;
766
767     if ($self->has_type_constraint) {
768         my $tc_obj = $self->type_constraint;
769
770         $env->{'$type_constraint'} = \(
771             $tc_obj->_compiled_type_constraint
772         ) unless $tc_obj->can_be_inlined;
773         # these two could probably get inlined versions too
774         $env->{'$type_coercion'} = \(
775             $tc_obj->coercion->_compiled_type_coercion
776         ) if $tc_obj->has_coercion;
777         $env->{'$type_message'} = \(
778             $tc_obj->has_message ? $tc_obj->message : $tc_obj->_default_message
779         );
780
781         $env = { %$env, %{ $tc_obj->inline_environment } };
782     }
783
784     # XXX ugh, fix these
785     $env->{'$attr'} = \$self
786         if $self->has_initializer && $self->is_lazy;
787     # pretty sure this is only going to be closed over if you use a custom
788     # error class at this point, but we should still get rid of this
789     # at some point
790     $env->{'$meta'} = \($self->associated_class);
791
792     return $env;
793 }
794
795 sub _weaken_value {
796     my ( $self, $instance ) = @_;
797
798     my $meta_instance = Class::MOP::Class->initialize( blessed($instance) )
799         ->get_meta_instance;
800
801     $meta_instance->weaken_slot_value( $instance, $self->name );
802 }
803
804 sub get_value {
805     my ($self, $instance, $for_trigger) = @_;
806
807     if ($self->is_lazy) {
808         unless ($self->has_value($instance)) {
809             my $value;
810             if ($self->has_default) {
811                 $value = $self->default($instance);
812             } elsif ( $self->has_builder ) {
813                 $value = $self->_call_builder($instance);
814             }
815
816             $value = $self->_coerce_and_verify( $value, $instance );
817
818             $self->set_initial_value($instance, $value);
819
820             if ( ref $value && $self->is_weak_ref ) {
821                 $self->_weaken_value($instance);
822             }
823         }
824     }
825
826     if ( $self->should_auto_deref && ! $for_trigger ) {
827
828         my $type_constraint = $self->type_constraint;
829
830         if ($type_constraint->is_a_type_of('ArrayRef')) {
831             my $rv = $self->SUPER::get_value($instance);
832             return unless defined $rv;
833             return wantarray ? @{ $rv } : $rv;
834         }
835         elsif ($type_constraint->is_a_type_of('HashRef')) {
836             my $rv = $self->SUPER::get_value($instance);
837             return unless defined $rv;
838             return wantarray ? %{ $rv } : $rv;
839         }
840         else {
841             $self->throw_error("Can not auto de-reference the type constraint '" . $type_constraint->name . "'", object => $instance, type_constraint => $type_constraint);
842         }
843
844     }
845     else {
846
847         return $self->SUPER::get_value($instance);
848     }
849 }
850
851 sub _inline_get_value {
852     my $self = shift;
853     my ($instance, $tc, $coercion, $message) = @_;
854
855     my $slot_access = $self->_inline_instance_get($instance);
856     $tc           ||= '$type_constraint';
857     $coercion     ||= '$type_coercion';
858     $message      ||= '$type_message';
859
860     return (
861         $self->_inline_check_lazy($instance, $tc, $coercion, $message),
862         $self->_inline_return_auto_deref($slot_access),
863     );
864 }
865
866 sub _inline_check_lazy {
867     my $self = shift;
868     my ($instance, $tc, $coercion, $message) = @_;
869
870     return unless $self->is_lazy;
871
872     my $slot_exists = $self->_inline_instance_has($instance);
873
874     return (
875         'if (!' . $slot_exists . ') {',
876             $self->_inline_init_from_default($instance, '$default', $tc, $coercion, $message, 'lazy'),
877         '}',
878     );
879 }
880
881 sub _inline_init_from_default {
882     my $self = shift;
883     my ($instance, $default, $tc, $coercion, $message, $for_lazy) = @_;
884
885     if (!($self->has_default || $self->has_builder)) {
886         $self->throw_error(
887             'You cannot have a lazy attribute '
888           . '(' . $self->name . ') '
889           . 'without specifying a default value for it',
890             attr => $self,
891         );
892     }
893
894     return (
895         $self->_inline_generate_default($instance, $default),
896         # intentionally not using _inline_tc_code, since that can be overridden
897         # to do things like possibly only do member tc checks, which isn't
898         # appropriate for checking the result of a default
899         $self->has_type_constraint
900             ? ($self->_inline_check_coercion($default, $tc, $coercion, $for_lazy),
901                $self->_inline_check_constraint($default, $tc, $message, $for_lazy))
902             : (),
903         $self->_inline_init_slot($instance, $default),
904         $self->_inline_weaken_value($instance, $default),
905     );
906 }
907
908 sub _inline_generate_default {
909     my $self = shift;
910     my ($instance, $default) = @_;
911
912     if ($self->has_default) {
913         my $source = 'my ' . $default . ' = $attr_default';
914         $source .= '->(' . $instance . ')'
915             if $self->is_default_a_coderef;
916         return $source . ';';
917     }
918     elsif ($self->has_builder) {
919         my $builder = B::perlstring($self->builder);
920         my $builder_str = quotemeta($self->builder);
921         my $attr_name_str = quotemeta($self->name);
922         return (
923             'my ' . $default . ';',
924             'if (my $builder = ' . $instance . '->can(' . $builder . ')) {',
925                 $default . ' = ' . $instance . '->$builder;',
926             '}',
927             'else {',
928                 'my $class = ref(' . $instance . ') || ' . $instance . ';',
929                 $self->_inline_throw_error(
930                     '"$class does not support builder method '
931                   . '\'' . $builder_str . '\' for attribute '
932                   . '\'' . $attr_name_str . '\'"'
933                 ) . ';',
934             '}',
935         );
936     }
937     else {
938         $self->throw_error(
939             "Can't generate a default for " . $self->name
940           . " since no default or builder was specified"
941         );
942     }
943 }
944
945 sub _inline_init_slot {
946     my $self = shift;
947     my ($inv, $value) = @_;
948
949     if ($self->has_initializer) {
950         return '$attr->set_initial_value(' . $inv . ', ' . $value . ');';
951     }
952     else {
953         return $self->_inline_instance_set($inv, $value) . ';';
954     }
955 }
956
957 sub _inline_return_auto_deref {
958     my $self = shift;
959
960     return 'return ' . $self->_auto_deref(@_) . ';';
961 }
962
963 sub _auto_deref {
964     my $self = shift;
965     my ($ref_value) = @_;
966
967     return $ref_value unless $self->should_auto_deref;
968
969     my $type_constraint = $self->type_constraint;
970
971     my $sigil;
972     if ($type_constraint->is_a_type_of('ArrayRef')) {
973         $sigil = '@';
974     }
975     elsif ($type_constraint->is_a_type_of('HashRef')) {
976         $sigil = '%';
977     }
978     else {
979         $self->throw_error(
980             'Can not auto de-reference the type constraint \''
981           . $type_constraint->name
982           . '\'',
983             type_constraint => $type_constraint,
984         );
985     }
986
987     return 'wantarray '
988              . '? ' . $sigil . '{ (' . $ref_value . ') || return } '
989              . ': (' . $ref_value . ')';
990 }
991
992 ## installing accessors
993
994 sub accessor_metaclass { 'Moose::Meta::Method::Accessor' }
995
996 sub install_accessors {
997     my $self = shift;
998     $self->SUPER::install_accessors(@_);
999     $self->install_delegation if $self->has_handles;
1000     return;
1001 }
1002
1003 sub _check_associated_methods {
1004     my $self = shift;
1005     unless (
1006         @{ $self->associated_methods }
1007         || ($self->_is_metadata || '') eq 'bare'
1008     ) {
1009         Carp::cluck(
1010             'Attribute (' . $self->name . ') of class '
1011             . $self->associated_class->name
1012             . ' has no associated methods'
1013             . ' (did you mean to provide an "is" argument?)'
1014             . "\n"
1015         )
1016     }
1017 }
1018
1019 sub _process_accessors {
1020     my $self = shift;
1021     my ($type, $accessor, $generate_as_inline_methods) = @_;
1022
1023     $accessor = ( keys %$accessor )[0] if ( ref($accessor) || '' ) eq 'HASH';
1024     my $method = $self->associated_class->get_method($accessor);
1025
1026     if (   $method
1027         && $method->isa('Class::MOP::Method::Accessor')
1028         && $method->associated_attribute->name ne $self->name ) {
1029
1030         my $other_attr_name = $method->associated_attribute->name;
1031         my $name            = $self->name;
1032
1033         Carp::cluck(
1034             "You are overwriting an accessor ($accessor) for the $other_attr_name attribute"
1035                 . " with a new accessor method for the $name attribute" );
1036     }
1037
1038     if (
1039            $method
1040         && !$method->is_stub
1041         && !$method->isa('Class::MOP::Method::Accessor')
1042         && (  !$self->definition_context
1043             || $method->package_name eq $self->definition_context->{package} )
1044         ) {
1045
1046         Carp::cluck(
1047             "You are overwriting a locally defined method ($accessor) with "
1048                 . "an accessor" );
1049     }
1050
1051     if (  !$self->associated_class->has_method($accessor)
1052         && $self->associated_class->has_package_symbol( '&' . $accessor ) ) {
1053
1054         Carp::cluck(
1055             "You are overwriting a locally defined function ($accessor) with "
1056                 . "an accessor" );
1057     }
1058
1059     $self->SUPER::_process_accessors(@_);
1060 }
1061
1062 sub remove_accessors {
1063     my $self = shift;
1064     $self->SUPER::remove_accessors(@_);
1065     $self->remove_delegation if $self->has_handles;
1066     return;
1067 }
1068
1069 sub install_delegation {
1070     my $self = shift;
1071
1072     # NOTE:
1073     # Here we canonicalize the 'handles' option
1074     # this will sort out any details and always
1075     # return an hash of methods which we want
1076     # to delagate to, see that method for details
1077     my %handles = $self->_canonicalize_handles;
1078
1079
1080     # install the delegation ...
1081     my $associated_class = $self->associated_class;
1082     foreach my $handle (sort keys %handles) {
1083         my $method_to_call = $handles{$handle};
1084         my $class_name = $associated_class->name;
1085         my $name = "${class_name}::${handle}";
1086
1087         if ( my $method = $associated_class->get_method($handle) ) {
1088             $self->throw_error(
1089                 "You cannot overwrite a locally defined method ($handle) with a delegation",
1090                 method_name => $handle
1091             ) unless $method->is_stub;
1092         }
1093
1094         # NOTE:
1095         # handles is not allowed to delegate
1096         # any of these methods, as they will
1097         # override the ones in your class, which
1098         # is almost certainly not what you want.
1099
1100         # FIXME warn when $handle was explicitly specified, but not if the source is a regex or something
1101         #cluck("Not delegating method '$handle' because it is a core method") and
1102         next if $class_name->isa("Moose::Object") and $handle =~ /^BUILD|DEMOLISH$/ || Moose::Object->can($handle);
1103
1104         my $method = $self->_make_delegation_method($handle, $method_to_call);
1105
1106         $self->associated_class->add_method($method->name, $method);
1107         $self->associate_method($method);
1108     }
1109 }
1110
1111 sub remove_delegation {
1112     my $self = shift;
1113     my %handles = $self->_canonicalize_handles;
1114     my $associated_class = $self->associated_class;
1115     foreach my $handle (keys %handles) {
1116         next unless any { $handle eq $_ }
1117                     map { $_->name }
1118                     @{ $self->associated_methods };
1119         $self->associated_class->remove_method($handle);
1120     }
1121 }
1122
1123 # private methods to help delegation ...
1124
1125 sub _canonicalize_handles {
1126     my $self    = shift;
1127     my $handles = $self->handles;
1128     if (my $handle_type = ref($handles)) {
1129         if ($handle_type eq 'HASH') {
1130             return %{$handles};
1131         }
1132         elsif ($handle_type eq 'ARRAY') {
1133             return map { $_ => $_ } @{$handles};
1134         }
1135         elsif ($handle_type eq 'Regexp') {
1136             ($self->has_type_constraint)
1137                 || $self->throw_error("Cannot delegate methods based on a Regexp without a type constraint (isa)", data => $handles);
1138             return map  { ($_ => $_) }
1139                    grep { /$handles/ } $self->_get_delegate_method_list;
1140         }
1141         elsif ($handle_type eq 'CODE') {
1142             return $handles->($self, $self->_find_delegate_metaclass);
1143         }
1144         elsif (blessed($handles) && $handles->isa('Moose::Meta::TypeConstraint::DuckType')) {
1145             return map { $_ => $_ } @{ $handles->methods };
1146         }
1147         elsif (blessed($handles) && $handles->isa('Moose::Meta::TypeConstraint::Role')) {
1148             $handles = $handles->role;
1149         }
1150         else {
1151             $self->throw_error("Unable to canonicalize the 'handles' option with $handles", data => $handles);
1152         }
1153     }
1154
1155     load_class($handles);
1156     my $role_meta = Class::MOP::class_of($handles);
1157
1158     (blessed $role_meta && $role_meta->isa('Moose::Meta::Role'))
1159         || $self->throw_error("Unable to canonicalize the 'handles' option with $handles because its metaclass is not a Moose::Meta::Role", data => $handles);
1160
1161     return map { $_ => $_ }
1162         map { $_->name }
1163         grep { !$_->isa('Class::MOP::Method::Meta') } (
1164         $role_meta->_get_local_methods,
1165         $role_meta->get_required_method_list,
1166         );
1167 }
1168
1169 sub _get_delegate_method_list {
1170     my $self = shift;
1171     my $meta = $self->_find_delegate_metaclass;
1172     if ($meta->isa('Class::MOP::Class')) {
1173         return map  { $_->name }  # NOTE: !never! delegate &meta
1174                grep { $_->package_name ne 'Moose::Object' && !$_->isa('Class::MOP::Method::Meta') }
1175                     $meta->get_all_methods;
1176     }
1177     elsif ($meta->isa('Moose::Meta::Role')) {
1178         return $meta->get_method_list;
1179     }
1180     else {
1181         $self->throw_error("Unable to recognize the delegate metaclass '$meta'", data => $meta);
1182     }
1183 }
1184
1185 sub _find_delegate_metaclass {
1186     my $self = shift;
1187     if (my $class = $self->_isa_metadata) {
1188         unless ( is_class_loaded($class) ) {
1189             $self->throw_error(
1190                 sprintf(
1191                     'The %s attribute is trying to delegate to a class which has not been loaded - %s',
1192                     $self->name, $class
1193                 )
1194             );
1195         }
1196         # we might be dealing with a non-Moose class,
1197         # and need to make our own metaclass. if there's
1198         # already a metaclass, it will be returned
1199         return Class::MOP::Class->initialize($class);
1200     }
1201     elsif (my $role = $self->_does_metadata) {
1202         unless ( is_class_loaded($class) ) {
1203             $self->throw_error(
1204                 sprintf(
1205                     'The %s attribute is trying to delegate to a role which has not been loaded - %s',
1206                     $self->name, $role
1207                 )
1208             );
1209         }
1210
1211         return Class::MOP::class_of($role);
1212     }
1213     else {
1214         $self->throw_error("Cannot find delegate metaclass for attribute " . $self->name);
1215     }
1216 }
1217
1218 sub delegation_metaclass { 'Moose::Meta::Method::Delegation' }
1219
1220 sub _make_delegation_method {
1221     my ( $self, $handle_name, $method_to_call ) = @_;
1222
1223     my @curried_arguments;
1224
1225     ($method_to_call, @curried_arguments) = @$method_to_call
1226         if 'ARRAY' eq ref($method_to_call);
1227
1228     return $self->delegation_metaclass->new(
1229         name               => $handle_name,
1230         package_name       => $self->associated_class->name,
1231         attribute          => $self,
1232         delegate_to_method => $method_to_call,
1233         curried_arguments  => \@curried_arguments,
1234     );
1235 }
1236
1237 sub _coerce_and_verify {
1238     my $self     = shift;
1239     my $val      = shift;
1240     my $instance = shift;
1241
1242     return $val unless $self->has_type_constraint;
1243
1244     $val = $self->type_constraint->coerce($val)
1245         if $self->should_coerce && $self->type_constraint->has_coercion;
1246
1247     $self->verify_against_type_constraint($val, instance => $instance);
1248
1249     return $val;
1250 }
1251
1252 sub verify_against_type_constraint {
1253     my $self = shift;
1254     my $val  = shift;
1255
1256     return 1 if !$self->has_type_constraint;
1257
1258     my $type_constraint = $self->type_constraint;
1259
1260     $type_constraint->check($val)
1261         || $self->throw_error(
1262                 superclass => 'Moose::Exception::TypeConstraint',
1263                 message => "Attribute ("
1264                  . $self->name
1265                  . ") does not pass the type constraint because: "
1266                  . $type_constraint->get_message($val),
1267                  value => $val,
1268                  attribute_name => $self->name,
1269                  type_name => $type_constraint->name,
1270                  @_);
1271 }
1272
1273 package Moose::Meta::Attribute::Custom::Moose;
1274 sub register_implementation { 'Moose::Meta::Attribute' }
1275
1276 1;
1277
1278 # ABSTRACT: The Moose attribute metaclass
1279
1280 __END__
1281
1282 =pod
1283
1284 =head1 DESCRIPTION
1285
1286 This class is a subclass of L<Class::MOP::Attribute> that provides
1287 additional Moose-specific functionality.
1288
1289 To really understand this class, you will need to start with the
1290 L<Class::MOP::Attribute> documentation. This class can be understood
1291 as a set of additional features on top of the basic feature provided
1292 by that parent class.
1293
1294 =head1 INHERITANCE
1295
1296 C<Moose::Meta::Attribute> is a subclass of L<Class::MOP::Attribute>.
1297
1298 =head1 METHODS
1299
1300 Many of the documented below override methods in
1301 L<Class::MOP::Attribute> and add Moose specific features.
1302
1303 =head2 Creation
1304
1305 =over 4
1306
1307 =item B<< Moose::Meta::Attribute->new(%options) >>
1308
1309 This method overrides the L<Class::MOP::Attribute> constructor.
1310
1311 Many of the options below are described in more detail in the
1312 L<Moose::Manual::Attributes> document.
1313
1314 It adds the following options to the constructor:
1315
1316 =over 8
1317
1318 =item * is => 'ro', 'rw', 'bare'
1319
1320 This provides a shorthand for specifying the C<reader>, C<writer>, or
1321 C<accessor> names. If the attribute is read-only ('ro') then it will
1322 have a C<reader> method with the same attribute as the name.
1323
1324 If it is read-write ('rw') then it will have an C<accessor> method
1325 with the same name. If you provide an explicit C<writer> for a
1326 read-write attribute, then you will have a C<reader> with the same
1327 name as the attribute, and a C<writer> with the name you provided.
1328
1329 Use 'bare' when you are deliberately not installing any methods
1330 (accessor, reader, etc.) associated with this attribute; otherwise,
1331 Moose will issue a deprecation warning when this attribute is added to a
1332 metaclass.
1333
1334 =item * isa => $type
1335
1336 This option accepts a type. The type can be a string, which should be
1337 a type name. If the type name is unknown, it is assumed to be a class
1338 name.
1339
1340 This option can also accept a L<Moose::Meta::TypeConstraint> object.
1341
1342 If you I<also> provide a C<does> option, then your C<isa> option must
1343 be a class name, and that class must do the role specified with
1344 C<does>.
1345
1346 =item * does => $role
1347
1348 This is short-hand for saying that the attribute's type must be an
1349 object which does the named role.
1350
1351 =item * coerce => $bool
1352
1353 This option is only valid for objects with a type constraint
1354 (C<isa>) that defined a coercion. If this is true, then coercions will be applied whenever
1355 this attribute is set.
1356
1357 You can make both this and the C<weak_ref> option true.
1358
1359 =item * trigger => $sub
1360
1361 This option accepts a subroutine reference, which will be called after
1362 the attribute is set.
1363
1364 =item * required => $bool
1365
1366 An attribute which is required must be provided to the constructor. An
1367 attribute which is required can also have a C<default> or C<builder>,
1368 which will satisfy its required-ness.
1369
1370 A required attribute must have a C<default>, C<builder> or a
1371 non-C<undef> C<init_arg>
1372
1373 =item * lazy => $bool
1374
1375 A lazy attribute must have a C<default> or C<builder>. When an
1376 attribute is lazy, the default value will not be calculated until the
1377 attribute is read.
1378
1379 =item * weak_ref => $bool
1380
1381 If this is true, the attribute's value will be stored as a weak
1382 reference.
1383
1384 =item * auto_deref => $bool
1385
1386 If this is true, then the reader will dereference the value when it is
1387 called. The attribute must have a type constraint which defines the
1388 attribute as an array or hash reference.
1389
1390 =item * lazy_build => $bool
1391
1392 Setting this to true makes the attribute lazy and provides a number of
1393 default methods.
1394
1395   has 'size' => (
1396       is         => 'ro',
1397       lazy_build => 1,
1398   );
1399
1400 is equivalent to this:
1401
1402   has 'size' => (
1403       is        => 'ro',
1404       lazy      => 1,
1405       builder   => '_build_size',
1406       clearer   => 'clear_size',
1407       predicate => 'has_size',
1408   );
1409
1410
1411 If your attribute name starts with an underscore (C<_>), then the clearer
1412 and predicate will as well:
1413
1414   has '_size' => (
1415       is         => 'ro',
1416       lazy_build => 1,
1417   );
1418
1419 becomes:
1420
1421   has '_size' => (
1422       is        => 'ro',
1423       lazy      => 1,
1424       builder   => '_build__size',
1425       clearer   => '_clear_size',
1426       predicate => '_has_size',
1427   );
1428
1429 Note the doubled underscore in the builder name. Internally, Moose
1430 simply prepends the attribute name with "_build_" to come up with the
1431 builder name.
1432
1433 =item * documentation
1434
1435 An arbitrary string that can be retrieved later by calling C<<
1436 $attr->documentation >>.
1437
1438 =back
1439
1440 =item B<< $attr->clone(%options) >>
1441
1442 This creates a new attribute based on attribute being cloned. You must
1443 supply a C<name> option to provide a new name for the attribute.
1444
1445 The C<%options> can only specify options handled by
1446 L<Class::MOP::Attribute>.
1447
1448 =back
1449
1450 =head2 Value management
1451
1452 =over 4
1453
1454 =item B<< $attr->initialize_instance_slot($meta_instance, $instance, $params) >>
1455
1456 This method is used internally to initialize the attribute's slot in
1457 the object C<$instance>.
1458
1459 This overrides the L<Class::MOP::Attribute> method to handle lazy
1460 attributes, weak references, and type constraints.
1461
1462 =item B<get_value>
1463
1464 =item B<set_value>
1465
1466   eval { $point->meta->get_attribute('x')->set_value($point, 'forty-two') };
1467   if($@) {
1468     print "Oops: $@\n";
1469   }
1470
1471 I<Attribute (x) does not pass the type constraint (Int) with 'forty-two'>
1472
1473 Before setting the value, a check is made on the type constraint of
1474 the attribute, if it has one, to see if the value passes it. If the
1475 value fails to pass, the set operation dies.
1476
1477 Any coercion to convert values is done before checking the type constraint.
1478
1479 To check a value against a type constraint before setting it, fetch the
1480 attribute instance using L<Class::MOP::Class/find_attribute_by_name>,
1481 fetch the type_constraint from the attribute using L<Moose::Meta::Attribute/type_constraint>
1482 and call L<Moose::Meta::TypeConstraint/check>. See L<Moose::Cookbook::Basics::Company_Subtypes>
1483 for an example.
1484
1485 =back
1486
1487 =head2 Attribute Accessor generation
1488
1489 =over 4
1490
1491 =item B<< $attr->install_accessors >>
1492
1493 This method overrides the parent to also install delegation methods.
1494
1495 If, after installing all methods, the attribute object has no associated
1496 methods, it throws an error unless C<< is => 'bare' >> was passed to the
1497 attribute constructor.  (Trying to add an attribute that has no associated
1498 methods is almost always an error.)
1499
1500 =item B<< $attr->remove_accessors >>
1501
1502 This method overrides the parent to also remove delegation methods.
1503
1504 =item B<< $attr->inline_set($instance_var, $value_var) >>
1505
1506 This method return a code snippet suitable for inlining the relevant
1507 operation. It expect strings containing variable names to be used in the
1508 inlining, like C<'$self'> or C<'$_[1]'>.
1509
1510 =item B<< $attr->install_delegation >>
1511
1512 This method adds its delegation methods to the attribute's associated
1513 class, if it has any to add.
1514
1515 =item B<< $attr->remove_delegation >>
1516
1517 This method remove its delegation methods from the attribute's
1518 associated class.
1519
1520 =item B<< $attr->accessor_metaclass >>
1521
1522 Returns the accessor metaclass name, which defaults to
1523 L<Moose::Meta::Method::Accessor>.
1524
1525 =item B<< $attr->delegation_metaclass >>
1526
1527 Returns the delegation metaclass name, which defaults to
1528 L<Moose::Meta::Method::Delegation>.
1529
1530 =back
1531
1532 =head2 Additional Moose features
1533
1534 These methods are not found in the superclass. They support features
1535 provided by Moose.
1536
1537 =over 4
1538
1539 =item B<< $attr->does($role) >>
1540
1541 This indicates whether the I<attribute itself> does the given
1542 role. The role can be given as a full class name, or as a resolvable
1543 trait name.
1544
1545 Note that this checks the attribute itself, not its type constraint,
1546 so it is checking the attribute's metaclass and any traits applied to
1547 the attribute.
1548
1549 =item B<< Moose::Meta::Class->interpolate_class_and_new($name, %options) >>
1550
1551 This is an alternate constructor that handles the C<metaclass> and
1552 C<traits> options.
1553
1554 Effectively, this method is a factory that finds or creates the
1555 appropriate class for the given C<metaclass> and/or C<traits>.
1556
1557 Once it has the appropriate class, it will call C<< $class->new($name,
1558 %options) >> on that class.
1559
1560 =item B<< $attr->clone_and_inherit_options(%options) >>
1561
1562 This method supports the C<has '+foo'> feature. It does various bits
1563 of processing on the supplied C<%options> before ultimately calling
1564 the C<clone> method.
1565
1566 One of its main tasks is to make sure that the C<%options> provided
1567 does not include the options returned by the
1568 C<illegal_options_for_inheritance> method.
1569
1570 =item B<< $attr->illegal_options_for_inheritance >>
1571
1572 This returns a blacklist of options that can not be overridden in a
1573 subclass's attribute definition.
1574
1575 This exists to allow a custom metaclass to change or add to the list
1576 of options which can not be changed.
1577
1578 =item B<< $attr->type_constraint >>
1579
1580 Returns the L<Moose::Meta::TypeConstraint> object for this attribute,
1581 if it has one.
1582
1583 =item B<< $attr->has_type_constraint >>
1584
1585 Returns true if this attribute has a type constraint.
1586
1587 =item B<< $attr->verify_against_type_constraint($value) >>
1588
1589 Given a value, this method returns true if the value is valid for the
1590 attribute's type constraint. If the value is not valid, it throws an
1591 error.
1592
1593 =item B<< $attr->handles >>
1594
1595 This returns the value of the C<handles> option passed to the
1596 constructor.
1597
1598 =item B<< $attr->has_handles >>
1599
1600 Returns true if this attribute performs delegation.
1601
1602 =item B<< $attr->is_weak_ref >>
1603
1604 Returns true if this attribute stores its value as a weak reference.
1605
1606 =item B<< $attr->is_required >>
1607
1608 Returns true if this attribute is required to have a value.
1609
1610 =item B<< $attr->is_lazy >>
1611
1612 Returns true if this attribute is lazy.
1613
1614 =item B<< $attr->is_lazy_build >>
1615
1616 Returns true if the C<lazy_build> option was true when passed to the
1617 constructor.
1618
1619 =item B<< $attr->should_coerce >>
1620
1621 Returns true if the C<coerce> option passed to the constructor was
1622 true.
1623
1624 =item B<< $attr->should_auto_deref >>
1625
1626 Returns true if the C<auto_deref> option passed to the constructor was
1627 true.
1628
1629 =item B<< $attr->trigger >>
1630
1631 This is the subroutine reference that was in the C<trigger> option
1632 passed to the constructor, if any.
1633
1634 =item B<< $attr->has_trigger >>
1635
1636 Returns true if this attribute has a trigger set.
1637
1638 =item B<< $attr->documentation >>
1639
1640 Returns the value that was in the C<documentation> option passed to
1641 the constructor, if any.
1642
1643 =item B<< $attr->has_documentation >>
1644
1645 Returns true if this attribute has any documentation.
1646
1647 =item B<< $attr->applied_traits >>
1648
1649 This returns an array reference of all the traits which were applied
1650 to this attribute. If none were applied, this returns C<undef>.
1651
1652 =item B<< $attr->has_applied_traits >>
1653
1654 Returns true if this attribute has any traits applied.
1655
1656 =back
1657
1658 =head1 BUGS
1659
1660 See L<Moose/BUGS> for details on reporting bugs.
1661
1662 =cut