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