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