2 package Moose::Meta::Attribute;
7 use Scalar::Util 'blessed', 'weaken';
10 our $VERSION = '0.72';
11 our $AUTHORITY = 'cpan:STEVAN';
13 use Moose::Meta::Method::Accessor;
14 use Moose::Meta::Method::Delegation;
16 use Moose::Util::TypeConstraints ();
18 use base 'Class::MOP::Attribute';
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'));
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',
37 __PACKAGE__->meta->add_attribute('trigger' => (
39 predicate => 'has_trigger',
41 __PACKAGE__->meta->add_attribute('handles' => (
43 predicate => 'has_handles',
45 __PACKAGE__->meta->add_attribute('documentation' => (
46 reader => 'documentation',
47 predicate => 'has_documentation',
49 __PACKAGE__->meta->add_attribute('traits' => (
50 reader => 'applied_traits',
51 predicate => 'has_applied_traits',
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.
59 my ($self, $role_name) = @_;
61 Moose::Util::resolve_metatrait_alias(Attribute => $role_name)
63 return 0 if !defined($name); # failed to load class
64 return $self->Moose::Object::does($name);
69 my $class = ( ref $self && $self->associated_class ) || "Moose::Meta::Class";
70 unshift @_, "message" if @_ % 2 == 1;
71 unshift @_, attr => $self if ref $self;
73 my $handler = $class->can("throw_error"); # to avoid incrementing depth by 1
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 return $class->SUPER::new($name, %options);
83 sub interpolate_class_and_new {
84 my ($class, $name, @args) = @_;
86 my ( $new_class, @traits ) = $class->interpolate_class(@args);
88 $new_class->new($name, @args, ( scalar(@traits) ? ( traits => \@traits ) : () ) );
91 sub interpolate_class {
92 my ($class, %options) = @_;
94 $class = ref($class) || $class;
96 if ( my $metaclass_name = delete $options{metaclass} ) {
97 my $new_class = Moose::Util::resolve_metaclass_alias( Attribute => $metaclass_name );
99 if ( $class ne $new_class ) {
100 if ( $new_class->can("interpolate_class") ) {
101 return $new_class->interpolate_class(%options);
110 if (my $traits = $options{traits}) {
112 while ($i < @$traits) {
113 my $trait = $traits->[$i++];
114 next if ref($trait); # options to a trait we discarded
116 $trait = Moose::Util::resolve_metatrait_alias(Attribute => $trait)
119 next if $class->does($trait);
121 push @traits, $trait;
124 push @traits, $traits->[$i++]
125 if $traits->[$i] && ref($traits->[$i]);
129 my $anon_class = Moose::Meta::Class->create_anon_class(
130 superclasses => [ $class ],
131 roles => [ @traits ],
135 $class = $anon_class->name;
139 return ( wantarray ? ( $class, @traits ) : $class );
144 my @legal_options_for_inheritance = qw(
145 default coerce required
146 documentation lazy handles
147 builder type_constraint
152 sub legal_options_for_inheritance { @legal_options_for_inheritance }
155 # This method *must* be able to handle
156 # Class::MOP::Attribute instances as
157 # well. Yes, I know that is wrong, but
158 # apparently we didn't realize it was
159 # doing that and now we have some code
160 # which is dependent on it. The real
161 # solution of course is to push this
162 # feature back up into Class::MOP::Attribute
163 # but I not right now, I am too lazy.
164 # However if you are reading this and
165 # looking for something to do,.. please
168 sub clone_and_inherit_options {
169 my ($self, %options) = @_;
176 # we may want to extends a Class::MOP::Attribute
177 # in which case we need to be able to use the
178 # core set of legal options that have always
179 # been here. But we allows Moose::Meta::Attribute
180 # instances to changes them.
182 my @legal_options = $self->can('legal_options_for_inheritance')
183 ? $self->legal_options_for_inheritance
184 : @legal_options_for_inheritance;
186 foreach my $legal_option (@legal_options) {
187 if (exists $options{$legal_option}) {
188 $actual_options{$legal_option} = $options{$legal_option};
189 delete $options{$legal_option};
195 if (blessed($options{isa}) && $options{isa}->isa('Moose::Meta::TypeConstraint')) {
196 $type_constraint = $options{isa};
199 $type_constraint = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options{isa});
200 (defined $type_constraint)
201 || $self->throw_error("Could not find the type constraint '" . $options{isa} . "'", data => $options{isa});
204 $actual_options{type_constraint} = $type_constraint;
205 delete $options{isa};
208 if ($options{does}) {
210 if (blessed($options{does}) && $options{does}->isa('Moose::Meta::TypeConstraint')) {
211 $type_constraint = $options{does};
214 $type_constraint = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options{does});
215 (defined $type_constraint)
216 || $self->throw_error("Could not find the type constraint '" . $options{does} . "'", data => $options{does});
219 $actual_options{type_constraint} = $type_constraint;
220 delete $options{does};
224 # this doesn't apply to Class::MOP::Attributes,
225 # so we can ignore it for them.
227 if ($self->can('interpolate_class')) {
228 ( $actual_options{metaclass}, my @traits ) = $self->interpolate_class(%options);
231 my @all_traits = grep { $seen{$_}++ } @{ $self->applied_traits || [] }, @traits;
232 $actual_options{traits} = \@all_traits if @all_traits;
234 delete @options{qw(metaclass traits)};
237 (scalar keys %options == 0)
238 || $self->throw_error("Illegal inherited options => (" . (join ', ' => keys %options) . ")", data => \%options);
241 $self->clone(%actual_options);
245 my ( $self, %params ) = @_;
247 my $class = $params{metaclass} || ref $self;
249 my ( @init, @non_init );
251 foreach my $attr ( grep { $_->has_value($self) } $self->meta->compute_all_applicable_attributes ) {
252 push @{ $attr->has_init_arg ? \@init : \@non_init }, $attr;
255 my %new_params = ( ( map { $_->init_arg => $_->get_value($self) } @init ), %params );
257 my $name = delete $new_params{name};
259 my $clone = $class->new($name, %new_params, __hack_no_process_options => 1 );
261 foreach my $attr ( @non_init ) {
262 $attr->set_value($clone, $attr->get_value($self));
268 sub _process_options {
269 my ($class, $name, $options) = @_;
271 if (exists $options->{is}) {
273 ### -------------------------
274 ## is => ro, writer => _foo # turns into (reader => foo, writer => _foo) as before
275 ## is => rw, writer => _foo # turns into (reader => foo, writer => _foo)
276 ## is => rw, accessor => _foo # turns into (accessor => _foo)
277 ## is => ro, accessor => _foo # error, accesor is rw
278 ### -------------------------
280 if ($options->{is} eq 'ro') {
281 $class->throw_error("Cannot define an accessor name on a read-only attribute, accessors are read/write", data => $options)
282 if exists $options->{accessor};
283 $options->{reader} ||= $name;
285 elsif ($options->{is} eq 'rw') {
286 if ($options->{writer}) {
287 $options->{reader} ||= $name;
290 $options->{accessor} ||= $name;
294 $class->throw_error("I do not understand this option (is => " . $options->{is} . ") on attribute ($name)", data => $options->{is});
298 if (exists $options->{isa}) {
299 if (exists $options->{does}) {
300 if (eval { $options->{isa}->can('does') }) {
301 ($options->{isa}->does($options->{does}))
302 || $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);
305 $class->throw_error("Cannot have an isa option which cannot ->does() on attribute ($name)", data => $options);
309 # allow for anon-subtypes here ...
310 if (blessed($options->{isa}) && $options->{isa}->isa('Moose::Meta::TypeConstraint')) {
311 $options->{type_constraint} = $options->{isa};
314 $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options->{isa});
317 elsif (exists $options->{does}) {
318 # allow for anon-subtypes here ...
319 if (blessed($options->{does}) && $options->{does}->isa('Moose::Meta::TypeConstraint')) {
320 $options->{type_constraint} = $options->{does};
323 $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options->{does});
327 if (exists $options->{coerce} && $options->{coerce}) {
328 (exists $options->{type_constraint})
329 || $class->throw_error("You cannot have coercion without specifying a type constraint on attribute ($name)", data => $options);
330 $class->throw_error("You cannot have a weak reference to a coerced value on attribute ($name)", data => $options)
331 if $options->{weak_ref};
334 if (exists $options->{trigger}) {
335 ('CODE' eq ref $options->{trigger})
336 || $class->throw_error("Trigger must be a CODE ref on attribute ($name)", data => $options->{trigger});
339 if (exists $options->{auto_deref} && $options->{auto_deref}) {
340 (exists $options->{type_constraint})
341 || $class->throw_error("You cannot auto-dereference without specifying a type constraint on attribute ($name)", data => $options);
342 ($options->{type_constraint}->is_a_type_of('ArrayRef') ||
343 $options->{type_constraint}->is_a_type_of('HashRef'))
344 || $class->throw_error("You cannot auto-dereference anything other than a ArrayRef or HashRef on attribute ($name)", data => $options);
347 if (exists $options->{lazy_build} && $options->{lazy_build} == 1) {
348 $class->throw_error("You can not use lazy_build and default for the same attribute ($name)", data => $options)
349 if exists $options->{default};
350 $options->{lazy} = 1;
351 $options->{required} = 1;
352 $options->{builder} ||= "_build_${name}";
354 $options->{clearer} ||= "_clear${name}";
355 $options->{predicate} ||= "_has${name}";
358 $options->{clearer} ||= "clear_${name}";
359 $options->{predicate} ||= "has_${name}";
363 if (exists $options->{lazy} && $options->{lazy}) {
364 (exists $options->{default} || defined $options->{builder} )
365 || $class->throw_error("You cannot have lazy attribute ($name) without specifying a default value for it", data => $options);
368 if ( $options->{required} && !( ( !exists $options->{init_arg} || defined $options->{init_arg} ) || exists $options->{default} || defined $options->{builder} ) ) {
369 $class->throw_error("You cannot have a required attribute ($name) without a default, builder, or an init_arg", data => $options);
374 sub initialize_instance_slot {
375 my ($self, $meta_instance, $instance, $params) = @_;
376 my $init_arg = $self->init_arg();
377 # try to fetch the init arg from the %params ...
381 if ( defined($init_arg) and exists $params->{$init_arg}) {
382 $val = $params->{$init_arg};
386 # skip it if it's lazy
387 return if $self->is_lazy;
388 # and die if it's required and doesn't have a default value
389 $self->throw_error("Attribute (" . $self->name . ") is required", object => $instance, data => $params)
390 if $self->is_required && !$self->has_default && !$self->has_builder;
392 # if nothing was in the %params, we can use the
393 # attribute's default value (if it has one)
394 if ($self->has_default) {
395 $val = $self->default($instance);
398 elsif ($self->has_builder) {
399 $val = $self->_call_builder($instance);
404 return unless $value_is_set;
406 if ($self->has_type_constraint) {
407 my $type_constraint = $self->type_constraint;
408 if ($self->should_coerce && $type_constraint->has_coercion) {
409 $val = $type_constraint->coerce($val);
411 $self->verify_against_type_constraint($val, instance => $instance);
414 $self->set_initial_value($instance, $val);
415 $meta_instance->weaken_slot_value($instance, $self->name)
416 if ref $val && $self->is_weak_ref;
420 my ( $self, $instance ) = @_;
422 my $builder = $self->builder();
424 return $instance->$builder()
425 if $instance->can( $self->builder );
427 $self->throw_error( blessed($instance)
428 . " does not support builder method '"
430 . "' for attribute '"
440 # this duplicates too much code from
441 # Class::MOP::Attribute, we need to
442 # refactor these bits eventually.
444 sub _set_initial_slot_value {
445 my ($self, $meta_instance, $instance, $value) = @_;
447 my $slot_name = $self->name;
449 return $meta_instance->set_slot_value($instance, $slot_name, $value)
450 unless $self->has_initializer;
452 my ($type_constraint, $can_coerce);
453 if ($self->has_type_constraint) {
454 $type_constraint = $self->type_constraint;
455 $can_coerce = ($self->should_coerce && $type_constraint->has_coercion);
460 if ($type_constraint) {
461 $val = $type_constraint->coerce($val)
463 $self->verify_against_type_constraint($val, object => $instance);
465 $meta_instance->set_slot_value($instance, $slot_name, $val);
468 my $initializer = $self->initializer;
470 # most things will just want to set a value, so make it first arg
471 $instance->$initializer($value, $callback, $self);
475 my ($self, $instance, @args) = @_;
476 my $value = $args[0];
478 my $attr_name = $self->name;
480 if ($self->is_required and not @args) {
481 $self->throw_error("Attribute ($attr_name) is required", object => $instance);
484 if ($self->has_type_constraint) {
486 my $type_constraint = $self->type_constraint;
488 if ($self->should_coerce) {
489 $value = $type_constraint->coerce($value);
491 $type_constraint->_compiled_type_constraint->($value)
492 || $self->throw_error("Attribute ("
494 . ") does not pass the type constraint because "
495 . $type_constraint->get_message($value), object => $instance, data => $value);
498 my $meta_instance = Class::MOP::Class->initialize(blessed($instance))
501 $meta_instance->set_slot_value($instance, $attr_name, $value);
503 if (ref $value && $self->is_weak_ref) {
504 $meta_instance->weaken_slot_value($instance, $attr_name);
507 if ($self->has_trigger) {
508 $self->trigger->($instance, $value);
513 my ($self, $instance) = @_;
515 if ($self->is_lazy) {
516 unless ($self->has_value($instance)) {
518 if ($self->has_default) {
519 $value = $self->default($instance);
520 } elsif ( $self->has_builder ) {
521 $value = $self->_call_builder($instance);
523 if ($self->has_type_constraint) {
524 my $type_constraint = $self->type_constraint;
525 $value = $type_constraint->coerce($value)
526 if ($self->should_coerce);
527 $self->verify_against_type_constraint($value);
529 $self->set_initial_value($instance, $value);
533 if ($self->should_auto_deref) {
535 my $type_constraint = $self->type_constraint;
537 if ($type_constraint->is_a_type_of('ArrayRef')) {
538 my $rv = $self->SUPER::get_value($instance);
539 return unless defined $rv;
540 return wantarray ? @{ $rv } : $rv;
542 elsif ($type_constraint->is_a_type_of('HashRef')) {
543 my $rv = $self->SUPER::get_value($instance);
544 return unless defined $rv;
545 return wantarray ? %{ $rv } : $rv;
548 $self->throw_error("Can not auto de-reference the type constraint '" . $type_constraint->name . "'", object => $instance, type_constraint => $type_constraint);
554 return $self->SUPER::get_value($instance);
558 ## installing accessors
560 sub accessor_metaclass { 'Moose::Meta::Method::Accessor' }
562 sub install_accessors {
564 $self->SUPER::install_accessors(@_);
565 $self->install_delegation if $self->has_handles;
569 sub remove_accessors {
571 $self->SUPER::remove_accessors(@_);
572 $self->remove_delegation if $self->has_handles;
576 sub install_delegation {
580 # Here we canonicalize the 'handles' option
581 # this will sort out any details and always
582 # return an hash of methods which we want
583 # to delagate to, see that method for details
584 my %handles = $self->_canonicalize_handles;
587 # install the delegation ...
588 my $associated_class = $self->associated_class;
589 foreach my $handle (keys %handles) {
590 my $method_to_call = $handles{$handle};
591 my $class_name = $associated_class->name;
592 my $name = "${class_name}::${handle}";
594 (!$associated_class->has_method($handle))
595 || $self->throw_error("You cannot overwrite a locally defined method ($handle) with a delegation", method_name => $handle);
598 # handles is not allowed to delegate
599 # any of these methods, as they will
600 # override the ones in your class, which
601 # is almost certainly not what you want.
603 # FIXME warn when $handle was explicitly specified, but not if the source is a regex or something
604 #cluck("Not delegating method '$handle' because it is a core method") and
605 next if $class_name->isa("Moose::Object") and $handle =~ /^BUILD|DEMOLISH$/ || Moose::Object->can($handle);
607 my $method = $self->_make_delegation_method($handle, $method_to_call);
609 $self->associated_class->add_method($method->name, $method);
613 sub remove_delegation {
615 my %handles = $self->_canonicalize_handles;
616 my $associated_class = $self->associated_class;
617 foreach my $handle (keys %handles) {
618 $self->associated_class->remove_method($handle);
622 # private methods to help delegation ...
624 sub _canonicalize_handles {
626 my $handles = $self->handles;
627 if (my $handle_type = ref($handles)) {
628 if ($handle_type eq 'HASH') {
631 elsif ($handle_type eq 'ARRAY') {
632 return map { $_ => $_ } @{$handles};
634 elsif ($handle_type eq 'Regexp') {
635 ($self->has_type_constraint)
636 || $self->throw_error("Cannot delegate methods based on a Regexp without a type constraint (isa)", data => $handles);
637 return map { ($_ => $_) }
638 grep { /$handles/ } $self->_get_delegate_method_list;
640 elsif ($handle_type eq 'CODE') {
641 return $handles->($self, $self->_find_delegate_metaclass);
644 $self->throw_error("Unable to canonicalize the 'handles' option with $handles", data => $handles);
648 Class::MOP::load_class($handles)
649 unless Class::MOP::is_class_loaded($handles);
651 my $role_meta = eval { $handles->meta };
653 $self->throw_error("Unable to canonicalize the 'handles' option with $handles because : $@", data => $handles, error => $@);
656 (blessed $role_meta && $role_meta->isa('Moose::Meta::Role'))
657 || $self->throw_error("Unable to canonicalize the 'handles' option with $handles because ->meta is not a Moose::Meta::Role", data => $handles);
659 return map { $_ => $_ } (
660 $role_meta->get_method_list,
661 $role_meta->get_required_method_list
666 sub _find_delegate_metaclass {
668 if (my $class = $self->_isa_metadata) {
669 # if the class does have
670 # a meta method, use it
671 return $class->meta if $class->can('meta');
672 # otherwise we might be
673 # dealing with a non-Moose
674 # class, and need to make
676 return Moose::Meta::Class->initialize($class);
678 elsif (my $role = $self->_does_metadata) {
679 # our role will always have
684 $self->throw_error("Cannot find delegate metaclass for attribute " . $self->name);
688 sub _get_delegate_method_list {
690 my $meta = $self->_find_delegate_metaclass;
691 if ($meta->isa('Class::MOP::Class')) {
692 return map { $_->name } # NOTE: !never! delegate &meta
693 grep { $_->package_name ne 'Moose::Object' && $_->name ne 'meta' }
694 $meta->get_all_methods;
696 elsif ($meta->isa('Moose::Meta::Role')) {
697 return $meta->get_method_list;
700 $self->throw_error("Unable to recognize the delegate metaclass '$meta'", data => $meta);
704 sub delegation_metaclass { 'Moose::Meta::Method::Delegation' }
706 sub _make_delegation_method {
707 my ( $self, $handle_name, $method_to_call ) = @_;
711 $method_body = $method_to_call
712 if 'CODE' eq ref($method_to_call);
714 return $self->delegation_metaclass->new(
715 name => $handle_name,
716 package_name => $self->associated_class->name,
718 delegate_to_method => $method_to_call,
722 sub verify_against_type_constraint {
726 return 1 if !$self->has_type_constraint;
728 my $type_constraint = $self->type_constraint;
730 $type_constraint->check($val)
731 || $self->throw_error("Attribute ("
733 . ") does not pass the type constraint because: "
734 . $type_constraint->get_message($val), data => $val, @_);
737 package Moose::Meta::Attribute::Custom::Moose;
738 sub register_implementation { 'Moose::Meta::Attribute' }
748 Moose::Meta::Attribute - The Moose attribute metaclass
752 This is a subclass of L<Class::MOP::Attribute> with Moose specific
755 For the most part, the only time you will ever encounter an
756 instance of this class is if you are doing some serious deep
757 introspection. To really understand this class, you need to refer
758 to the L<Class::MOP::Attribute> documentation.
762 =head2 Overridden methods
764 These methods override methods in L<Class::MOP::Attribute> and add
765 Moose specific features. You can safely assume though that they
766 will behave just as L<Class::MOP::Attribute> does.
776 =item B<initialize_instance_slot>
778 =item B<install_accessors>
780 =item B<remove_accessors>
782 =item B<install_delegation>
784 =item B<remove_delegation>
786 =item B<accessor_metaclass>
788 =item B<delegation_metaclass>
794 eval { $point->meta->get_attribute('x')->set_value($point, 'forty-two') };
799 I<Attribute (x) does not pass the type constraint (Int) with 'forty-two'>
801 Before setting the value, a check is made on the type constraint of
802 the attribute, if it has one, to see if the value passes it. If the
803 value fails to pass, the set operation dies with a L<throw_error>.
805 Any coercion to convert values is done before checking the type constraint.
807 To check a value against a type constraint before setting it, fetch the
808 attribute instance using L<Class::MOP::Class/find_attribute_by_name>,
809 fetch the type_constraint from the attribute using L<Moose::Meta::Attribute/type_constraint>
810 and call L<Moose::Meta::TypeConstraint/check>. See L<Moose::Cookbook::Basics::Recipe4>
815 =head2 Additional Moose features
817 Moose attributes support type-constraint checking, weak reference
818 creation and type coercion.
824 Delegates to C<associated_class> or C<Moose::Meta::Class> if there is none.
826 =item B<interpolate_class_and_new>
828 =item B<interpolate_class>
830 When called as a class method causes interpretation of the C<metaclass> and
833 =item B<clone_and_inherit_options>
835 This is to support the C<has '+foo'> feature, it clones an attribute
836 from a superclass and allows a very specific set of changes to be made
839 =item B<legal_options_for_inheritance>
841 Whitelist with options you can change. You can overload it in your custom
842 metaclass to allow your options be inheritable.
844 =item B<has_type_constraint>
846 Returns true if this meta-attribute has a type constraint.
848 =item B<type_constraint>
850 A read-only accessor for this meta-attribute's type constraint. For
851 more information on what you can do with this, see the documentation
852 for L<Moose::Meta::TypeConstraint>.
854 =item B<verify_against_type_constraint>
856 Verifies that the given value is valid under this attribute's type
857 constraint, otherwise throws an error.
861 Returns true if this meta-attribute performs delegation.
865 This returns the value which was passed into the handles option.
869 Returns true if this meta-attribute produces a weak reference.
873 Returns true if this meta-attribute is required to have a value.
877 Returns true if this meta-attribute should be initialized lazily.
879 NOTE: lazy attributes, B<must> have a C<default> or C<builder> field set.
881 =item B<is_lazy_build>
883 Returns true if this meta-attribute should be initialized lazily through
884 the builder generated by lazy_build. Using C<lazy_build =E<gt> 1> will
885 make your attribute required and lazy. In addition it will set the builder, clearer
886 and predicate options for you using the following convention.
888 #If your attribute name starts with an underscore:
889 has '_foo' => (lazy_build => 1);
891 has '_foo' => (lazy => 1, required => 1, predicate => '_has_foo', clearer => '_clear_foo', builder => '_build__foo');
893 has '_foo' => (lazy => 1, required => 1, predicate => '_has_foo', clearer => '_clear_foo', default => sub{shift->_build__foo});
895 #If your attribute name does not start with an underscore:
896 has 'foo' => (lazy_build => 1);
898 has 'foo' => (lazy => 1, required => 1, predicate => 'has_foo', clearer => 'clear_foo', builder => '_build_foo');
900 has 'foo' => (lazy => 1, required => 1, predicate => 'has_foo', clearer => 'clear_foo', default => sub{shift->_build_foo});
902 The reason for the different naming of the C<builder> is that the C<builder>
903 method is a private method while the C<clearer> and C<predicate> methods
906 NOTE: This means your class should provide a method whose name matches the value
907 of the builder part, in this case _build__foo or _build_foo.
909 =item B<should_coerce>
911 Returns true if this meta-attribute should perform type coercion.
913 =item B<should_auto_deref>
915 Returns true if this meta-attribute should perform automatic
918 NOTE: This can only be done for attributes whose type constraint is
919 either I<ArrayRef> or I<HashRef>.
923 Returns true if this meta-attribute has a trigger set.
927 This is a CODE reference which will be executed every time the
928 value of an attribute is assigned. The CODE ref will get two values,
929 the invocant and the new value. This can be used to handle I<basic>
930 bi-directional relations.
932 =item B<documentation>
934 This is a string which contains the documentation for this attribute.
935 It serves no direct purpose right now, but it might in the future
936 in some kind of automated documentation system perhaps.
938 =item B<has_documentation>
940 Returns true if this meta-attribute has any documentation.
942 =item B<applied_traits>
944 This will return the ARRAY ref of all the traits applied to this
945 attribute, or if no traits have been applied, it returns C<undef>.
947 =item B<has_applied_traits>
949 Returns true if this meta-attribute has any traits applied.
955 All complex software has bugs lurking in it, and this module is no
956 exception. If you find a bug please either email me, or add the bug
961 Stevan Little E<lt>stevan@iinteractive.comE<gt>
963 Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
965 =head1 COPYRIGHT AND LICENSE
967 Copyright 2006-2009 by Infinity Interactive, Inc.
969 L<http://www.iinteractive.com>
971 This library is free software; you can redistribute it and/or modify
972 it under the same terms as Perl itself.