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