Include the class name in the method-less attribute message
[gitmo/Moose.git] / lib / Moose / Meta / Attribute.pm
1
2 package Moose::Meta::Attribute;
3
4 use strict;
5 use warnings;
6
7 use Scalar::Util 'blessed', 'weaken';
8 use overload     ();
9
10 our $VERSION   = '0.84';
11 our $AUTHORITY = 'cpan:STEVAN';
12
13 use Moose::Meta::Method::Accessor;
14 use Moose::Meta::Method::Delegation;
15 use Moose::Util ();
16 use Moose::Util::TypeConstraints ();
17
18 use base 'Class::MOP::Attribute';
19
20 # options which are not directly used
21 # but we store them for metadata purposes
22 __PACKAGE__->meta->add_attribute('isa'  => (reader    => '_isa_metadata'));
23 __PACKAGE__->meta->add_attribute('does' => (reader    => '_does_metadata'));
24 __PACKAGE__->meta->add_attribute('is'   => (reader    => '_is_metadata'));
25
26 # these are actual options for the attrs
27 __PACKAGE__->meta->add_attribute('required'   => (reader => 'is_required'      ));
28 __PACKAGE__->meta->add_attribute('lazy'       => (reader => 'is_lazy'          ));
29 __PACKAGE__->meta->add_attribute('lazy_build' => (reader => 'is_lazy_build'    ));
30 __PACKAGE__->meta->add_attribute('coerce'     => (reader => 'should_coerce'    ));
31 __PACKAGE__->meta->add_attribute('weak_ref'   => (reader => 'is_weak_ref'      ));
32 __PACKAGE__->meta->add_attribute('auto_deref' => (reader => 'should_auto_deref'));
33 __PACKAGE__->meta->add_attribute('type_constraint' => (
34     reader    => 'type_constraint',
35     predicate => 'has_type_constraint',
36 ));
37 __PACKAGE__->meta->add_attribute('trigger' => (
38     reader    => 'trigger',
39     predicate => 'has_trigger',
40 ));
41 __PACKAGE__->meta->add_attribute('handles' => (
42     reader    => 'handles',
43     predicate => 'has_handles',
44 ));
45 __PACKAGE__->meta->add_attribute('documentation' => (
46     reader    => 'documentation',
47     predicate => 'has_documentation',
48 ));
49 __PACKAGE__->meta->add_attribute('traits' => (
50     reader    => 'applied_traits',
51     predicate => 'has_applied_traits',
52 ));
53
54 # we need to have a ->does method in here to
55 # more easily support traits, and the introspection
56 # of those traits. We extend the does check to look
57 # for metatrait aliases.
58 sub does {
59     my ($self, $role_name) = @_;
60     my $name = eval {
61         Moose::Util::resolve_metatrait_alias(Attribute => $role_name)
62     };
63     return 0 if !defined($name); # failed to load class
64     return $self->Moose::Object::does($name);
65 }
66
67 sub throw_error {
68     my $self = shift;
69     my $class = ( ref $self && $self->associated_class ) || "Moose::Meta::Class";
70     unshift @_, "message" if @_ % 2 == 1;
71     unshift @_, attr => $self if ref $self;
72     unshift @_, $class;
73     my $handler = $class->can("throw_error"); # to avoid incrementing depth by 1
74     goto $handler;
75 }
76
77 sub new {
78     my ($class, $name, %options) = @_;
79     $class->_process_options($name, \%options) unless $options{__hack_no_process_options}; # used from clone()... YECHKKK FIXME ICKY YUCK GROSS
80     
81     delete $options{__hack_no_process_options};
82
83     my %attrs =
84         ( map { $_ => 1 }
85           grep { defined }
86           map { $_->init_arg() }
87           $class->meta()->get_all_attributes()
88         );
89
90     my @bad = sort grep { ! $attrs{$_} }  keys %options;
91
92     if (@bad)
93     {
94         Carp::cluck "Found unknown argument(s) passed to '$name' attribute constructor in '$class': @bad";
95     }
96
97     return $class->SUPER::new($name, %options);
98 }
99
100 sub interpolate_class_and_new {
101     my ($class, $name, %args) = @_;
102
103     my ( $new_class, @traits ) = $class->interpolate_class(\%args);
104
105     $new_class->new($name, %args, ( scalar(@traits) ? ( traits => \@traits ) : () ) );
106 }
107
108 sub interpolate_class {
109     my ($class, $options) = @_;
110
111     $class = ref($class) || $class;
112
113     if ( my $metaclass_name = delete $options->{metaclass} ) {
114         my $new_class = Moose::Util::resolve_metaclass_alias( Attribute => $metaclass_name );
115
116         if ( $class ne $new_class ) {
117             if ( $new_class->can("interpolate_class") ) {
118                 return $new_class->interpolate_class($options);
119             } else {
120                 $class = $new_class;
121             }
122         }
123     }
124
125     my @traits;
126
127     if (my $traits = $options->{traits}) {
128         my $i = 0;
129         while ($i < @$traits) {
130             my $trait = $traits->[$i++];
131             next if ref($trait); # options to a trait we discarded
132
133             $trait = Moose::Util::resolve_metatrait_alias(Attribute => $trait)
134                   || $trait;
135
136             next if $class->does($trait);
137
138             push @traits, $trait;
139
140             # are there options?
141             push @traits, $traits->[$i++]
142                 if $traits->[$i] && ref($traits->[$i]);
143         }
144
145         if (@traits) {
146             my $anon_class = Moose::Meta::Class->create_anon_class(
147                 superclasses => [ $class ],
148                 roles        => [ @traits ],
149                 cache        => 1,
150             );
151
152             $class = $anon_class->name;
153         }
154     }
155
156     return ( wantarray ? ( $class, @traits ) : $class );
157 }
158
159 # ...
160
161 my @legal_options_for_inheritance = qw(
162     default coerce required
163     documentation lazy handles
164     builder type_constraint
165     definition_context
166     lazy_build
167 );
168
169 sub legal_options_for_inheritance { @legal_options_for_inheritance }
170
171 # NOTE/TODO
172 # This method *must* be able to handle
173 # Class::MOP::Attribute instances as
174 # well. Yes, I know that is wrong, but
175 # apparently we didn't realize it was
176 # doing that and now we have some code
177 # which is dependent on it. The real
178 # solution of course is to push this
179 # feature back up into Class::MOP::Attribute
180 # but I not right now, I am too lazy.
181 # However if you are reading this and
182 # looking for something to do,.. please
183 # be my guest.
184 # - stevan
185 sub clone_and_inherit_options {
186     my ($self, %options) = @_;
187
188     my %copy = %options;
189
190     my %actual_options;
191
192     # NOTE:
193     # we may want to extends a Class::MOP::Attribute
194     # in which case we need to be able to use the
195     # core set of legal options that have always
196     # been here. But we allows Moose::Meta::Attribute
197     # instances to changes them.
198     # - SL
199     my @legal_options = $self->can('legal_options_for_inheritance')
200         ? $self->legal_options_for_inheritance
201         : @legal_options_for_inheritance;
202
203     foreach my $legal_option (@legal_options) {
204         if (exists $options{$legal_option}) {
205             $actual_options{$legal_option} = $options{$legal_option};
206             delete $options{$legal_option};
207         }
208     }
209
210     if ($options{isa}) {
211         my $type_constraint;
212         if (blessed($options{isa}) && $options{isa}->isa('Moose::Meta::TypeConstraint')) {
213             $type_constraint = $options{isa};
214         }
215         else {
216             $type_constraint = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options{isa});
217             (defined $type_constraint)
218                 || $self->throw_error("Could not find the type constraint '" . $options{isa} . "'", data => $options{isa});
219         }
220
221         $actual_options{type_constraint} = $type_constraint;
222         delete $options{isa};
223     }
224
225     if ($options{does}) {
226         my $type_constraint;
227         if (blessed($options{does}) && $options{does}->isa('Moose::Meta::TypeConstraint')) {
228             $type_constraint = $options{does};
229         }
230         else {
231             $type_constraint = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options{does});
232             (defined $type_constraint)
233                 || $self->throw_error("Could not find the type constraint '" . $options{does} . "'", data => $options{does});
234         }
235
236         $actual_options{type_constraint} = $type_constraint;
237         delete $options{does};
238     }
239
240     # NOTE:
241     # this doesn't apply to Class::MOP::Attributes,
242     # so we can ignore it for them.
243     # - SL
244     if ($self->can('interpolate_class')) {
245         ( $actual_options{metaclass}, my @traits ) = $self->interpolate_class(\%options);
246
247         my %seen;
248         my @all_traits = grep { $seen{$_}++ } @{ $self->applied_traits || [] }, @traits;
249         $actual_options{traits} = \@all_traits if @all_traits;
250
251         delete @options{qw(metaclass traits)};
252     }
253
254     (scalar keys %options == 0)
255         || $self->throw_error("Illegal inherited options => (" . (join ', ' => keys %options) . ")", data => \%options);
256
257
258     $self->clone(%actual_options);
259 }
260
261 sub clone {
262     my ( $self, %params ) = @_;
263
264     my $class = delete $params{metaclass} || ref $self;
265
266     my ( @init, @non_init );
267
268     foreach my $attr ( grep { $_->has_value($self) } Class::MOP::class_of($self)->get_all_attributes ) {
269         push @{ $attr->has_init_arg ? \@init : \@non_init }, $attr;
270     }
271
272     my %new_params = ( ( map { $_->init_arg => $_->get_value($self) } @init ), %params );
273
274     my $name = delete $new_params{name};
275
276     my $clone = $class->new($name, %new_params, __hack_no_process_options => 1 );
277
278     foreach my $attr ( @non_init ) {
279         $attr->set_value($clone, $attr->get_value($self));
280     }
281
282     return $clone;
283 }
284
285 sub _process_options {
286     my ($class, $name, $options) = @_;
287
288     if (exists $options->{is}) {
289
290         ### -------------------------
291         ## is => ro, writer => _foo    # turns into (reader => foo, writer => _foo) as before
292         ## is => rw, writer => _foo    # turns into (reader => foo, writer => _foo)
293         ## is => rw, accessor => _foo  # turns into (accessor => _foo)
294         ## is => ro, accessor => _foo  # error, accesor is rw
295         ### -------------------------
296
297         if ($options->{is} eq 'ro') {
298             $class->throw_error("Cannot define an accessor name on a read-only attribute, accessors are read/write", data => $options)
299                 if exists $options->{accessor};
300             $options->{reader} ||= $name;
301         }
302         elsif ($options->{is} eq 'rw') {
303             if ($options->{writer}) {
304                 $options->{reader} ||= $name;
305             }
306             else {
307                 $options->{accessor} ||= $name;
308             }
309         }
310         elsif ($options->{is} eq 'bare') {
311             # do nothing, but don't complain (later) about missing methods
312         }
313         else {
314             $class->throw_error("I do not understand this option (is => " . $options->{is} . ") on attribute ($name)", data => $options->{is});
315         }
316     }
317
318     if (exists $options->{isa}) {
319         if (exists $options->{does}) {
320             if (eval { $options->{isa}->can('does') }) {
321                 ($options->{isa}->does($options->{does}))
322                     || $class->throw_error("Cannot have an isa option and a does option if the isa does not do the does on attribute ($name)", data => $options);
323             }
324             else {
325                 $class->throw_error("Cannot have an isa option which cannot ->does() on attribute ($name)", data => $options);
326             }
327         }
328
329         # allow for anon-subtypes here ...
330         if (blessed($options->{isa}) && $options->{isa}->isa('Moose::Meta::TypeConstraint')) {
331             $options->{type_constraint} = $options->{isa};
332         }
333         else {
334             $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options->{isa});
335         }
336     }
337     elsif (exists $options->{does}) {
338         # allow for anon-subtypes here ...
339         if (blessed($options->{does}) && $options->{does}->isa('Moose::Meta::TypeConstraint')) {
340                 $options->{type_constraint} = $options->{does};
341         }
342         else {
343             $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options->{does});
344         }
345     }
346
347     if (exists $options->{coerce} && $options->{coerce}) {
348         (exists $options->{type_constraint})
349             || $class->throw_error("You cannot have coercion without specifying a type constraint on attribute ($name)", data => $options);
350         $class->throw_error("You cannot have a weak reference to a coerced value on attribute ($name)", data => $options)
351             if $options->{weak_ref};
352     }
353
354     if (exists $options->{trigger}) {
355         ('CODE' eq ref $options->{trigger})
356             || $class->throw_error("Trigger must be a CODE ref on attribute ($name)", data => $options->{trigger});
357     }
358
359     if (exists $options->{auto_deref} && $options->{auto_deref}) {
360         (exists $options->{type_constraint})
361             || $class->throw_error("You cannot auto-dereference without specifying a type constraint on attribute ($name)", data => $options);
362         ($options->{type_constraint}->is_a_type_of('ArrayRef') ||
363          $options->{type_constraint}->is_a_type_of('HashRef'))
364             || $class->throw_error("You cannot auto-dereference anything other than a ArrayRef or HashRef on attribute ($name)", data => $options);
365     }
366
367     if (exists $options->{lazy_build} && $options->{lazy_build} == 1) {
368         $class->throw_error("You can not use lazy_build and default for the same attribute ($name)", data => $options)
369             if exists $options->{default};
370         $options->{lazy}      = 1;
371         $options->{builder} ||= "_build_${name}";
372         if ($name =~ /^_/) {
373             $options->{clearer}   ||= "_clear${name}";
374             $options->{predicate} ||= "_has${name}";
375         }
376         else {
377             $options->{clearer}   ||= "clear_${name}";
378             $options->{predicate} ||= "has_${name}";
379         }
380     }
381
382     if (exists $options->{lazy} && $options->{lazy}) {
383         (exists $options->{default} || defined $options->{builder} )
384             || $class->throw_error("You cannot have lazy attribute ($name) without specifying a default value for it", data => $options);
385     }
386
387     if ( $options->{required} && !( ( !exists $options->{init_arg} || defined $options->{init_arg} ) || exists $options->{default} || defined $options->{builder} ) ) {
388         $class->throw_error("You cannot have a required attribute ($name) without a default, builder, or an init_arg", data => $options);
389     }
390
391 }
392
393 sub initialize_instance_slot {
394     my ($self, $meta_instance, $instance, $params) = @_;
395     my $init_arg = $self->init_arg();
396     # try to fetch the init arg from the %params ...
397
398     my $val;
399     my $value_is_set;
400     if ( defined($init_arg) and exists $params->{$init_arg}) {
401         $val = $params->{$init_arg};
402         $value_is_set = 1;
403     }
404     else {
405         # skip it if it's lazy
406         return if $self->is_lazy;
407         # and die if it's required and doesn't have a default value
408         $self->throw_error("Attribute (" . $self->name . ") is required", object => $instance, data => $params)
409             if $self->is_required && !$self->has_default && !$self->has_builder;
410
411         # if nothing was in the %params, we can use the
412         # attribute's default value (if it has one)
413         if ($self->has_default) {
414             $val = $self->default($instance);
415             $value_is_set = 1;
416         }
417         elsif ($self->has_builder) {
418             $val = $self->_call_builder($instance);
419             $value_is_set = 1;
420         }
421     }
422
423     return unless $value_is_set;
424
425     $val = $self->_coerce_and_verify( $val, $instance );
426
427     $self->set_initial_value($instance, $val);
428     $meta_instance->weaken_slot_value($instance, $self->name)
429         if ref $val && $self->is_weak_ref;
430 }
431
432 sub _call_builder {
433     my ( $self, $instance ) = @_;
434
435     my $builder = $self->builder();
436
437     return $instance->$builder()
438         if $instance->can( $self->builder );
439
440     $self->throw_error(  blessed($instance)
441             . " does not support builder method '"
442             . $self->builder
443             . "' for attribute '"
444             . $self->name
445             . "'",
446             object => $instance,
447      );
448 }
449
450 ## Slot management
451
452 # FIXME:
453 # this duplicates too much code from
454 # Class::MOP::Attribute, we need to
455 # refactor these bits eventually.
456 # - SL
457 sub _set_initial_slot_value {
458     my ($self, $meta_instance, $instance, $value) = @_;
459
460     my $slot_name = $self->name;
461
462     return $meta_instance->set_slot_value($instance, $slot_name, $value)
463         unless $self->has_initializer;
464
465     my ($type_constraint, $can_coerce);
466     if ($self->has_type_constraint) {
467         $type_constraint = $self->type_constraint;
468         $can_coerce      = ($self->should_coerce && $type_constraint->has_coercion);
469     }
470
471     my $callback = sub {
472         my $val = $self->_coerce_and_verify( shift, $instance );;
473
474         $meta_instance->set_slot_value($instance, $slot_name, $val);
475     };
476
477     my $initializer = $self->initializer;
478
479     # most things will just want to set a value, so make it first arg
480     $instance->$initializer($value, $callback, $self);
481 }
482
483 sub set_value {
484     my ($self, $instance, @args) = @_;
485     my $value = $args[0];
486
487     my $attr_name = $self->name;
488
489     if ($self->is_required and not @args) {
490         $self->throw_error("Attribute ($attr_name) is required", object => $instance);
491     }
492
493     $value = $self->_coerce_and_verify( $value, $instance );
494
495     my $meta_instance = Class::MOP::Class->initialize(blessed($instance))
496                                          ->get_meta_instance;
497
498     $meta_instance->set_slot_value($instance, $attr_name, $value);
499
500     if (ref $value && $self->is_weak_ref) {
501         $meta_instance->weaken_slot_value($instance, $attr_name);
502     }
503
504     if ($self->has_trigger) {
505         $self->trigger->($instance, $value);
506     }
507 }
508
509 sub get_value {
510     my ($self, $instance) = @_;
511
512     if ($self->is_lazy) {
513         unless ($self->has_value($instance)) {
514             my $value;
515             if ($self->has_default) {
516                 $value = $self->default($instance);
517             } elsif ( $self->has_builder ) {
518                 $value = $self->_call_builder($instance);
519             }
520
521             $value = $self->_coerce_and_verify( $value, $instance );
522
523             $self->set_initial_value($instance, $value);
524         }
525     }
526
527     if ($self->should_auto_deref) {
528
529         my $type_constraint = $self->type_constraint;
530
531         if ($type_constraint->is_a_type_of('ArrayRef')) {
532             my $rv = $self->SUPER::get_value($instance);
533             return unless defined $rv;
534             return wantarray ? @{ $rv } : $rv;
535         }
536         elsif ($type_constraint->is_a_type_of('HashRef')) {
537             my $rv = $self->SUPER::get_value($instance);
538             return unless defined $rv;
539             return wantarray ? %{ $rv } : $rv;
540         }
541         else {
542             $self->throw_error("Can not auto de-reference the type constraint '" . $type_constraint->name . "'", object => $instance, type_constraint => $type_constraint);
543         }
544
545     }
546     else {
547
548         return $self->SUPER::get_value($instance);
549     }
550 }
551
552 ## installing accessors
553
554 sub accessor_metaclass { 'Moose::Meta::Method::Accessor' }
555
556 sub install_accessors {
557     my $self = shift;
558     $self->SUPER::install_accessors(@_);
559     $self->install_delegation if $self->has_handles;
560     unless (
561         @{ $self->associated_methods }
562         || ($self->_is_metadata || '') eq 'bare'
563     ) {
564         Carp::cluck(
565             'Attribute (' . $self->name . ') of class '
566             . $self->associated_class->name
567             . ' has no associated methods'
568             . ' (did you mean to provide an "is" argument?)'
569             . "\n"
570         )
571     }
572     return;
573 }
574
575 sub _process_accessors {
576     my $self = shift;
577     my ($type, $accessor, $generate_as_inline_methods) = @_;
578     $accessor = (keys %$accessor)[0] if (ref($accessor)||'') eq 'HASH';
579     my $method = $self->associated_class->get_method($accessor);
580     if ($method && !$method->isa('Class::MOP::Method::Accessor')
581      && (!$self->definition_context
582       || $method->package_name eq $self->definition_context->{package})) {
583         Carp::cluck(
584             "You cannot overwrite a locally defined method ($accessor) with "
585           . "an accessor"
586         );
587     }
588     $self->SUPER::_process_accessors(@_);
589 }
590
591 sub remove_accessors {
592     my $self = shift;
593     $self->SUPER::remove_accessors(@_);
594     $self->remove_delegation if $self->has_handles;
595     return;
596 }
597
598 sub install_delegation {
599     my $self = shift;
600
601     # NOTE:
602     # Here we canonicalize the 'handles' option
603     # this will sort out any details and always
604     # return an hash of methods which we want
605     # to delagate to, see that method for details
606     my %handles = $self->_canonicalize_handles;
607
608
609     # install the delegation ...
610     my $associated_class = $self->associated_class;
611     foreach my $handle (keys %handles) {
612         my $method_to_call = $handles{$handle};
613         my $class_name = $associated_class->name;
614         my $name = "${class_name}::${handle}";
615
616             (!$associated_class->has_method($handle))
617                 || $self->throw_error("You cannot overwrite a locally defined method ($handle) with a delegation", method_name => $handle);
618
619         # NOTE:
620         # handles is not allowed to delegate
621         # any of these methods, as they will
622         # override the ones in your class, which
623         # is almost certainly not what you want.
624
625         # FIXME warn when $handle was explicitly specified, but not if the source is a regex or something
626         #cluck("Not delegating method '$handle' because it is a core method") and
627         next if $class_name->isa("Moose::Object") and $handle =~ /^BUILD|DEMOLISH$/ || Moose::Object->can($handle);
628
629         my $method = $self->_make_delegation_method($handle, $method_to_call);
630
631         $self->associated_class->add_method($method->name, $method);
632         $self->associate_method($method);
633     }
634 }
635
636 sub remove_delegation {
637     my $self = shift;
638     my %handles = $self->_canonicalize_handles;
639     my $associated_class = $self->associated_class;
640     foreach my $handle (keys %handles) {
641         $self->associated_class->remove_method($handle);
642     }
643 }
644
645 # private methods to help delegation ...
646
647 sub _canonicalize_handles {
648     my $self    = shift;
649     my $handles = $self->handles;
650     if (my $handle_type = ref($handles)) {
651         if ($handle_type eq 'HASH') {
652             return %{$handles};
653         }
654         elsif ($handle_type eq 'ARRAY') {
655             return map { $_ => $_ } @{$handles};
656         }
657         elsif ($handle_type eq 'Regexp') {
658             ($self->has_type_constraint)
659                 || $self->throw_error("Cannot delegate methods based on a Regexp without a type constraint (isa)", data => $handles);
660             return map  { ($_ => $_) }
661                    grep { /$handles/ } $self->_get_delegate_method_list;
662         }
663         elsif ($handle_type eq 'CODE') {
664             return $handles->($self, $self->_find_delegate_metaclass);
665         }
666         elsif (blessed($handles) && $handles->isa('Moose::Meta::TypeConstraint::DuckType')) {
667             return map { $_ => $_ } @{ $handles->methods };
668         }
669         else {
670             $self->throw_error("Unable to canonicalize the 'handles' option with $handles", data => $handles);
671         }
672     }
673     else {
674         Class::MOP::load_class($handles);
675         my $role_meta = Class::MOP::class_of($handles);
676
677         (blessed $role_meta && $role_meta->isa('Moose::Meta::Role'))
678             || $self->throw_error("Unable to canonicalize the 'handles' option with $handles because its metaclass is not a Moose::Meta::Role", data => $handles);
679
680         return map { $_ => $_ } (
681             $role_meta->get_method_list,
682             map { $_->name } $role_meta->get_required_method_list,
683         );
684     }
685 }
686
687 sub _find_delegate_metaclass {
688     my $self = shift;
689     if (my $class = $self->_isa_metadata) {
690         # we might be dealing with a non-Moose class,
691         # and need to make our own metaclass. if there's
692         # already a metaclass, it will be returned
693         return Moose::Meta::Class->initialize($class);
694     }
695     elsif (my $role = $self->_does_metadata) {
696         return Class::MOP::class_of($role);
697     }
698     else {
699         $self->throw_error("Cannot find delegate metaclass for attribute " . $self->name);
700     }
701 }
702
703 sub _get_delegate_method_list {
704     my $self = shift;
705     my $meta = $self->_find_delegate_metaclass;
706     if ($meta->isa('Class::MOP::Class')) {
707         return map  { $_->name }  # NOTE: !never! delegate &meta
708                grep { $_->package_name ne 'Moose::Object' && $_->name ne 'meta' }
709                     $meta->get_all_methods;
710     }
711     elsif ($meta->isa('Moose::Meta::Role')) {
712         return $meta->get_method_list;
713     }
714     else {
715         $self->throw_error("Unable to recognize the delegate metaclass '$meta'", data => $meta);
716     }
717 }
718
719 sub delegation_metaclass { 'Moose::Meta::Method::Delegation' }
720
721 sub _make_delegation_method {
722     my ( $self, $handle_name, $method_to_call ) = @_;
723
724     my $method_body;
725
726     $method_body = $method_to_call
727         if 'CODE' eq ref($method_to_call);
728
729     return $self->delegation_metaclass->new(
730         name               => $handle_name,
731         package_name       => $self->associated_class->name,
732         attribute          => $self,
733         delegate_to_method => $method_to_call,
734     );
735 }
736
737 sub _coerce_and_verify {
738     my $self     = shift;
739     my $val      = shift;
740     my $instance = shift;
741
742     return $val unless $self->has_type_constraint;
743
744     my $type_constraint = $self->type_constraint;
745     if ($self->should_coerce && $type_constraint->has_coercion) {
746         $val = $type_constraint->coerce($val);
747     }
748
749     $self->verify_against_type_constraint($val, instance => $instance);
750
751     return $val;
752 }
753
754 sub verify_against_type_constraint {
755     my $self = shift;
756     my $val  = shift;
757
758     return 1 if !$self->has_type_constraint;
759
760     my $type_constraint = $self->type_constraint;
761
762     $type_constraint->check($val)
763         || $self->throw_error("Attribute ("
764                  . $self->name
765                  . ") does not pass the type constraint because: "
766                  . $type_constraint->get_message($val), data => $val, @_);
767 }
768
769 package Moose::Meta::Attribute::Custom::Moose;
770 sub register_implementation { 'Moose::Meta::Attribute' }
771
772 1;
773
774 __END__
775
776 =pod
777
778 =head1 NAME
779
780 Moose::Meta::Attribute - The Moose attribute metaclass
781
782 =head1 DESCRIPTION
783
784 This class is a subclass of L<Class::MOP::Attribute> that provides
785 additional Moose-specific functionality.
786
787 To really understand this class, you will need to start with the
788 L<Class::MOP::Attribute> documentation. This class can be understood
789 as a set of additional features on top of the basic feature provided
790 by that parent class.
791
792 =head1 INHERITANCE
793
794 C<Moose::Meta::Attribute> is a subclass of L<Class::MOP::Attribute>.
795
796 =head1 METHODS
797
798 Many of the documented below override methods in
799 L<Class::MOP::Attribute> and add Moose specific features.
800
801 =head2 Creation
802
803 =over 4
804
805 =item B<< Moose::Meta::Attribute->new(%options) >>
806
807 This method overrides the L<Class::MOP::Attribute> constructor.
808
809 Many of the options below are described in more detail in the
810 L<Moose::Manual::Attributes> document.
811
812 It adds the following options to the constructor:
813
814 =over 8
815
816 =item * is => 'ro', 'rw', 'bare'
817
818 This provides a shorthand for specifying the C<reader>, C<writer>, or
819 C<accessor> names. If the attribute is read-only ('ro') then it will
820 have a C<reader> method with the same attribute as the name.
821
822 If it is read-write ('rw') then it will have an C<accessor> method
823 with the same name. If you provide an explicit C<writer> for a
824 read-write attribute, then you will have a C<reader> with the same
825 name as the attribute, and a C<writer> with the name you provided.
826
827 Use 'bare' when you are deliberately not installing any methods
828 (accessor, reader, etc.) associated with this attribute; otherwise,
829 Moose will issue a deprecation warning when this attribute is added to a
830 metaclass.
831
832 =item * isa => $type
833
834 This option accepts a type. The type can be a string, which should be
835 a type name. If the type name is unknown, it is assumed to be a class
836 name.
837
838 This option can also accept a L<Moose::Meta::TypeConstraint> object.
839
840 If you I<also> provide a C<does> option, then your C<isa> option must
841 be a class name, and that class must do the role specified with
842 C<does>.
843
844 =item * does => $role
845
846 This is short-hand for saying that the attribute's type must be an
847 object which does the named role.
848
849 =item * coerce => $bool
850
851 This option is only valid for objects with a type constraint
852 (C<isa>). If this is true, then coercions will be applied whenever
853 this attribute is set.
854
855 You can make both this and the C<weak_ref> option true.
856
857 =item * trigger => $sub
858
859 This option accepts a subroutine reference, which will be called after
860 the attribute is set.
861
862 =item * required => $bool
863
864 An attribute which is required must be provided to the constructor. An
865 attribute which is required can also have a C<default> or C<builder>,
866 which will satisfy its required-ness.
867
868 A required attribute must have a C<default>, C<builder> or a
869 non-C<undef> C<init_arg>
870
871 =item * lazy => $bool
872
873 A lazy attribute must have a C<default> or C<builder>. When an
874 attribute is lazy, the default value will not be calculated until the
875 attribute is read.
876
877 =item * weak_ref => $bool
878
879 If this is true, the attribute's value will be stored as a weak
880 reference.
881
882 =item * auto_deref => $bool
883
884 If this is true, then the reader will dereference the value when it is
885 called. The attribute must have a type constraint which defines the
886 attribute as an array or hash reference.
887
888 =item * lazy_build => $bool
889
890 Setting this to true makes the attribute lazy and provides a number of
891 default methods.
892
893   has 'size' => (
894       is         => 'ro',
895       lazy_build => 1,
896   );
897
898 is equivalent to this:
899
900   has 'size' => (
901       is        => 'ro',
902       lazy      => 1,
903       builder   => '_build_size',
904       clearer   => 'clear_size',
905       predicate => 'has_size',
906   );
907
908 =item * documentation
909
910 An arbitrary string that can be retrieved later by calling C<<
911 $attr->documentation >>.
912
913 =back
914
915 =item B<< $attr->clone(%options) >>
916
917 This creates a new attribute based on attribute being cloned. You must
918 supply a C<name> option to provide a new name for the attribute.
919
920 The C<%options> can only specify options handled by
921 L<Class::MOP::Attribute>.
922
923 =back
924
925 =head2 Value management
926
927 =over 4
928
929 =item B<< $attr->initialize_instance_slot($meta_instance, $instance, $params) >>
930
931 This method is used internally to initialize the attribute's slot in
932 the object C<$instance>.
933
934 This overrides the L<Class::MOP::Attribute> method to handle lazy
935 attributes, weak references, and type constraints.
936
937 =item B<get_value>
938
939 =item B<set_value>
940
941   eval { $point->meta->get_attribute('x')->set_value($point, 'forty-two') };
942   if($@) {
943     print "Oops: $@\n";
944   }
945
946 I<Attribute (x) does not pass the type constraint (Int) with 'forty-two'>
947
948 Before setting the value, a check is made on the type constraint of
949 the attribute, if it has one, to see if the value passes it. If the
950 value fails to pass, the set operation dies with a L<throw_error>.
951
952 Any coercion to convert values is done before checking the type constraint.
953
954 To check a value against a type constraint before setting it, fetch the
955 attribute instance using L<Class::MOP::Class/find_attribute_by_name>,
956 fetch the type_constraint from the attribute using L<Moose::Meta::Attribute/type_constraint>
957 and call L<Moose::Meta::TypeConstraint/check>. See L<Moose::Cookbook::Basics::Recipe4>
958 for an example.
959
960 =back
961
962 =head2 Attribute Accessor generation
963
964 =over 4
965
966 =item B<< $attr->install_accessors >>
967
968 This method overrides the parent to also install delegation methods.
969
970 If, after installing all methods, the attribute object has no associated
971 methods, it throws an error unless C<< is => 'bare' >> was passed to the
972 attribute constructor.  (Trying to add an attribute that has no associated
973 methods is almost always an error.)
974
975 =item B<< $attr->remove_accessors >>
976
977 This method overrides the parent to also remove delegation methods.
978
979 =item B<< $attr->install_delegation >>
980
981 This method adds its delegation methods to the attribute's associated
982 class, if it has any to add.
983
984 =item B<< $attr->remove_delegation >>
985
986 This method remove its delegation methods from the attribute's
987 associated class.
988
989 =item B<< $attr->accessor_metaclass >>
990
991 Returns the accessor metaclass name, which defaults to
992 L<Moose::Meta::Method::Accessor>.
993
994 =item B<< $attr->delegation_metaclass >>
995
996 Returns the delegation metaclass name, which defaults to
997 L<Moose::Meta::Method::Delegation>.
998
999 =back
1000
1001 =head2 Additional Moose features
1002
1003 These methods are not found in the superclass. They support features
1004 provided by Moose.
1005
1006 =over 4
1007
1008 =item B<< $attr->does($role) >>
1009
1010 This indicates whether the I<attribute itself> does the given
1011 role. The role can be given as a full class name, or as a resolvable
1012 trait name.
1013
1014 Note that this checks the attribute itself, not its type constraint,
1015 so it is checking the attribute's metaclass and any traits applied to
1016 the attribute.
1017
1018 =item B<< Moose::Meta::Class->interpolate_class_and_new($name, %options) >>
1019
1020 This is an alternate constructor that handles the C<metaclass> and
1021 C<traits> options.
1022
1023 Effectively, this method is a factory that finds or creates the
1024 appropriate class for the given C<metaclass> and/or C<traits>.
1025
1026 Once it has the appropriate class, it will call C<< $class->new($name,
1027 %options) >> on that class.
1028
1029 =item B<< $attr->clone_and_inherit_options(%options) >>
1030
1031 This method supports the C<has '+foo'> feature. It does various bits
1032 of processing on the supplied C<%options> before ultimately calling
1033 the C<clone> method.
1034
1035 One of its main tasks is to make sure that the C<%options> provided
1036 only includes the options returned by the
1037 C<legal_options_for_inheritance> method.
1038
1039 =item B<< $attr->legal_options_for_inheritance >>
1040
1041 This returns a whitelist of options that can be overridden in a
1042 subclass's attribute definition.
1043
1044 This exists to allow a custom metaclass to change or add to the list
1045 of options which can be changed.
1046
1047 =item B<< $attr->type_constraint >>
1048
1049 Returns the L<Moose::Meta::TypeConstraint> object for this attribute,
1050 if it has one.
1051
1052 =item B<< $attr->has_type_constraint >>
1053
1054 Returns true if this attribute has a type constraint.
1055
1056 =item B<< $attr->verify_against_type_constraint($value) >>
1057
1058 Given a value, this method returns true if the value is valid for the
1059 attribute's type constraint. If the value is not valid, it throws an
1060 error.
1061
1062 =item B<< $attr->handles >>
1063
1064 This returns the value of the C<handles> option passed to the
1065 constructor.
1066
1067 =item B<< $attr->has_handles >>
1068
1069 Returns true if this attribute performs delegation.
1070
1071 =item B<< $attr->is_weak_ref >>
1072
1073 Returns true if this attribute stores its value as a weak reference.
1074
1075 =item B<< $attr->is_required >>
1076
1077 Returns true if this attribute is required to have a value.
1078
1079 =item B<< $attr->is_lazy >>
1080
1081 Returns true if this attribute is lazy.
1082
1083 =item B<< $attr->is_lazy_build >>
1084
1085 Returns true if the C<lazy_build> option was true when passed to the
1086 constructor.
1087
1088 =item B<< $attr->should_coerce >>
1089
1090 Returns true if the C<coerce> option passed to the constructor was
1091 true.
1092
1093 =item B<< $attr->should_auto_deref >>
1094
1095 Returns true if the C<auto_deref> option passed to the constructor was
1096 true.
1097
1098 =item B<< $attr->trigger >>
1099
1100 This is the subroutine reference that was in the C<trigger> option
1101 passed to the constructor, if any.
1102
1103 =item B<< $attr->has_trigger >>
1104
1105 Returns true if this attribute has a trigger set.
1106
1107 =item B<< $attr->documentation >>
1108
1109 Returns the value that was in the C<documentation> option passed to
1110 the constructor, if any.
1111
1112 =item B<< $attr->has_documentation >>
1113
1114 Returns true if this attribute has any documentation.
1115
1116 =item B<< $attr->applied_traits >>
1117
1118 This returns an array reference of all the traits which were applied
1119 to this attribute. If none were applied, this returns C<undef>.
1120
1121 =item B<< $attr->has_applied_traits >>
1122
1123 Returns true if this attribute has any traits applied.
1124
1125 =back
1126
1127 =head1 BUGS
1128
1129 All complex software has bugs lurking in it, and this module is no
1130 exception. If you find a bug please either email me, or add the bug
1131 to cpan-RT.
1132
1133 =head1 AUTHOR
1134
1135 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1136
1137 Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
1138
1139 =head1 COPYRIGHT AND LICENSE
1140
1141 Copyright 2006-2009 by Infinity Interactive, Inc.
1142
1143 L<http://www.iinteractive.com>
1144
1145 This library is free software; you can redistribute it and/or modify
1146 it under the same terms as Perl itself.
1147
1148 =cut