2 package Moose::Meta::Attribute;
7 use Scalar::Util 'blessed', 'weaken';
10 our $VERSION = '0.71';
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
151 sub legal_options_for_inheritance { @legal_options_for_inheritance }
154 # This method *must* be able to handle
155 # Class::MOP::Attribute instances as
156 # well. Yes, I know that is wrong, but
157 # apparently we didn't realize it was
158 # doing that and now we have some code
159 # which is dependent on it. The real
160 # solution of course is to push this
161 # feature back up into Class::MOP::Attribute
162 # but I not right now, I am too lazy.
163 # However if you are reading this and
164 # looking for something to do,.. please
167 sub clone_and_inherit_options {
168 my ($self, %options) = @_;
175 # we may want to extends a Class::MOP::Attribute
176 # in which case we need to be able to use the
177 # core set of legal options that have always
178 # been here. But we allows Moose::Meta::Attribute
179 # instances to changes them.
181 my @legal_options = $self->can('legal_options_for_inheritance')
182 ? $self->legal_options_for_inheritance
183 : @legal_options_for_inheritance;
185 foreach my $legal_option (@legal_options) {
186 if (exists $options{$legal_option}) {
187 $actual_options{$legal_option} = $options{$legal_option};
188 delete $options{$legal_option};
194 if (blessed($options{isa}) && $options{isa}->isa('Moose::Meta::TypeConstraint')) {
195 $type_constraint = $options{isa};
198 $type_constraint = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options{isa});
199 (defined $type_constraint)
200 || $self->throw_error("Could not find the type constraint '" . $options{isa} . "'", data => $options{isa});
203 $actual_options{type_constraint} = $type_constraint;
204 delete $options{isa};
207 if ($options{does}) {
209 if (blessed($options{does}) && $options{does}->isa('Moose::Meta::TypeConstraint')) {
210 $type_constraint = $options{does};
213 $type_constraint = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options{does});
214 (defined $type_constraint)
215 || $self->throw_error("Could not find the type constraint '" . $options{does} . "'", data => $options{does});
218 $actual_options{type_constraint} = $type_constraint;
219 delete $options{does};
223 # this doesn't apply to Class::MOP::Attributes,
224 # so we can ignore it for them.
226 if ($self->can('interpolate_class')) {
227 ( $actual_options{metaclass}, my @traits ) = $self->interpolate_class(%options);
230 my @all_traits = grep { $seen{$_}++ } @{ $self->applied_traits || [] }, @traits;
231 $actual_options{traits} = \@all_traits if @all_traits;
233 delete @options{qw(metaclass traits)};
236 (scalar keys %options == 0)
237 || $self->throw_error("Illegal inherited options => (" . (join ', ' => keys %options) . ")", data => \%options);
240 $self->clone(%actual_options);
244 my ( $self, %params ) = @_;
246 my $class = $params{metaclass} || ref $self;
248 if ( 0 and $class eq ref $self ) {
249 return $self->SUPER::clone(%params);
251 my ( @init, @non_init );
253 foreach my $attr ( grep { $_->has_value($self) } $self->meta->compute_all_applicable_attributes ) {
254 push @{ $attr->has_init_arg ? \@init : \@non_init }, $attr;
257 my %new_params = ( ( map { $_->init_arg => $_->get_value($self) } @init ), %params );
259 my $name = delete $new_params{name};
261 my $clone = $class->new($name, %new_params, __hack_no_process_options => 1 );
263 foreach my $attr ( @non_init ) {
264 $attr->set_value($clone, $attr->get_value($self));
272 sub _process_options {
273 my ($class, $name, $options) = @_;
275 if (exists $options->{is}) {
277 ### -------------------------
278 ## is => ro, writer => _foo # turns into (reader => foo, writer => _foo) as before
279 ## is => rw, writer => _foo # turns into (reader => foo, writer => _foo)
280 ## is => rw, accessor => _foo # turns into (accessor => _foo)
281 ## is => ro, accessor => _foo # error, accesor is rw
282 ### -------------------------
284 if ($options->{is} eq 'ro') {
285 $class->throw_error("Cannot define an accessor name on a read-only attribute, accessors are read/write", data => $options)
286 if exists $options->{accessor};
287 $options->{reader} ||= $name;
289 elsif ($options->{is} eq 'rw') {
290 if ($options->{writer}) {
291 $options->{reader} ||= $name;
294 $options->{accessor} ||= $name;
298 $class->throw_error("I do not understand this option (is => " . $options->{is} . ") on attribute ($name)", data => $options->{is});
302 if (exists $options->{isa}) {
303 if (exists $options->{does}) {
304 if (eval { $options->{isa}->can('does') }) {
305 ($options->{isa}->does($options->{does}))
306 || $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);
309 $class->throw_error("Cannot have an isa option which cannot ->does() on attribute ($name)", data => $options);
313 # allow for anon-subtypes here ...
314 if (blessed($options->{isa}) && $options->{isa}->isa('Moose::Meta::TypeConstraint')) {
315 $options->{type_constraint} = $options->{isa};
318 $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options->{isa});
321 elsif (exists $options->{does}) {
322 # allow for anon-subtypes here ...
323 if (blessed($options->{does}) && $options->{does}->isa('Moose::Meta::TypeConstraint')) {
324 $options->{type_constraint} = $options->{does};
327 $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options->{does});
331 if (exists $options->{coerce} && $options->{coerce}) {
332 (exists $options->{type_constraint})
333 || $class->throw_error("You cannot have coercion without specifying a type constraint on attribute ($name)", data => $options);
334 $class->throw_error("You cannot have a weak reference to a coerced value on attribute ($name)", data => $options)
335 if $options->{weak_ref};
338 if (exists $options->{trigger}) {
339 ('CODE' eq ref $options->{trigger})
340 || $class->throw_error("Trigger must be a CODE ref on attribute ($name)", data => $options->{trigger});
343 if (exists $options->{auto_deref} && $options->{auto_deref}) {
344 (exists $options->{type_constraint})
345 || $class->throw_error("You cannot auto-dereference without specifying a type constraint on attribute ($name)", data => $options);
346 ($options->{type_constraint}->is_a_type_of('ArrayRef') ||
347 $options->{type_constraint}->is_a_type_of('HashRef'))
348 || $class->throw_error("You cannot auto-dereference anything other than a ArrayRef or HashRef on attribute ($name)", data => $options);
351 if (exists $options->{lazy_build} && $options->{lazy_build} == 1) {
352 $class->throw_error("You can not use lazy_build and default for the same attribute ($name)", data => $options)
353 if exists $options->{default};
354 $options->{lazy} = 1;
355 $options->{required} = 1;
356 $options->{builder} ||= "_build_${name}";
358 $options->{clearer} ||= "_clear${name}";
359 $options->{predicate} ||= "_has${name}";
362 $options->{clearer} ||= "clear_${name}";
363 $options->{predicate} ||= "has_${name}";
367 if (exists $options->{lazy} && $options->{lazy}) {
368 (exists $options->{default} || defined $options->{builder} )
369 || $class->throw_error("You cannot have lazy attribute ($name) without specifying a default value for it", data => $options);
372 if ( $options->{required} && !( ( !exists $options->{init_arg} || defined $options->{init_arg} ) || exists $options->{default} || defined $options->{builder} ) ) {
373 $class->throw_error("You cannot have a required attribute ($name) without a default, builder, or an init_arg", data => $options);
378 sub initialize_instance_slot {
379 my ($self, $meta_instance, $instance, $params) = @_;
380 my $init_arg = $self->init_arg();
381 # try to fetch the init arg from the %params ...
385 if ( defined($init_arg) and exists $params->{$init_arg}) {
386 $val = $params->{$init_arg};
390 # skip it if it's lazy
391 return if $self->is_lazy;
392 # and die if it's required and doesn't have a default value
393 $self->throw_error("Attribute (" . $self->name . ") is required", object => $instance, data => $params)
394 if $self->is_required && !$self->has_default && !$self->has_builder;
396 # if nothing was in the %params, we can use the
397 # attribute's default value (if it has one)
398 if ($self->has_default) {
399 $val = $self->default($instance);
402 elsif ($self->has_builder) {
403 $val = $self->_call_builder($instance);
408 return unless $value_is_set;
410 if ($self->has_type_constraint) {
411 my $type_constraint = $self->type_constraint;
412 if ($self->should_coerce && $type_constraint->has_coercion) {
413 $val = $type_constraint->coerce($val);
415 $self->verify_against_type_constraint($val, instance => $instance);
418 $self->set_initial_value($instance, $val);
419 $meta_instance->weaken_slot_value($instance, $self->name)
420 if ref $val && $self->is_weak_ref;
424 my ( $self, $instance ) = @_;
426 my $builder = $self->builder();
428 return $instance->$builder()
429 if $instance->can( $self->builder );
431 $self->throw_error( blessed($instance)
432 . " does not support builder method '"
434 . "' for attribute '"
444 # this duplicates too much code from
445 # Class::MOP::Attribute, we need to
446 # refactor these bits eventually.
448 sub _set_initial_slot_value {
449 my ($self, $meta_instance, $instance, $value) = @_;
451 my $slot_name = $self->name;
453 return $meta_instance->set_slot_value($instance, $slot_name, $value)
454 unless $self->has_initializer;
456 my ($type_constraint, $can_coerce);
457 if ($self->has_type_constraint) {
458 $type_constraint = $self->type_constraint;
459 $can_coerce = ($self->should_coerce && $type_constraint->has_coercion);
464 if ($type_constraint) {
465 $val = $type_constraint->coerce($val)
467 $self->verify_against_type_constraint($val, object => $instance);
469 $meta_instance->set_slot_value($instance, $slot_name, $val);
472 my $initializer = $self->initializer;
474 # most things will just want to set a value, so make it first arg
475 $instance->$initializer($value, $callback, $self);
479 my ($self, $instance, @args) = @_;
480 my $value = $args[0];
482 my $attr_name = $self->name;
484 if ($self->is_required and not @args) {
485 $self->throw_error("Attribute ($attr_name) is required", object => $instance);
488 if ($self->has_type_constraint) {
490 my $type_constraint = $self->type_constraint;
492 if ($self->should_coerce) {
493 $value = $type_constraint->coerce($value);
495 $type_constraint->_compiled_type_constraint->($value)
496 || $self->throw_error("Attribute ("
498 . ") does not pass the type constraint because "
499 . $type_constraint->get_message($value), object => $instance, data => $value);
502 my $meta_instance = Class::MOP::Class->initialize(blessed($instance))
505 $meta_instance->set_slot_value($instance, $attr_name, $value);
507 if (ref $value && $self->is_weak_ref) {
508 $meta_instance->weaken_slot_value($instance, $attr_name);
511 if ($self->has_trigger) {
512 $self->trigger->($instance, $value);
517 my ($self, $instance) = @_;
519 if ($self->is_lazy) {
520 unless ($self->has_value($instance)) {
522 if ($self->has_default) {
523 $value = $self->default($instance);
524 } elsif ( $self->has_builder ) {
525 $value = $self->_call_builder($instance);
527 if ($self->has_type_constraint) {
528 my $type_constraint = $self->type_constraint;
529 $value = $type_constraint->coerce($value)
530 if ($self->should_coerce);
531 $self->verify_against_type_constraint($value);
533 $self->set_initial_value($instance, $value);
537 if ($self->should_auto_deref) {
539 my $type_constraint = $self->type_constraint;
541 if ($type_constraint->is_a_type_of('ArrayRef')) {
542 my $rv = $self->SUPER::get_value($instance);
543 return unless defined $rv;
544 return wantarray ? @{ $rv } : $rv;
546 elsif ($type_constraint->is_a_type_of('HashRef')) {
547 my $rv = $self->SUPER::get_value($instance);
548 return unless defined $rv;
549 return wantarray ? %{ $rv } : $rv;
552 $self->throw_error("Can not auto de-reference the type constraint '" . $type_constraint->name . "'", object => $instance, type_constraint => $type_constraint);
558 return $self->SUPER::get_value($instance);
562 ## installing accessors
564 sub accessor_metaclass { 'Moose::Meta::Method::Accessor' }
566 sub install_accessors {
568 $self->SUPER::install_accessors(@_);
569 $self->install_delegation if $self->has_handles;
573 sub remove_accessors {
575 $self->SUPER::remove_accessors(@_);
576 $self->remove_delegation if $self->has_handles;
580 sub install_delegation {
584 # Here we canonicalize the 'handles' option
585 # this will sort out any details and always
586 # return an hash of methods which we want
587 # to delagate to, see that method for details
588 my %handles = $self->_canonicalize_handles;
591 # install the delegation ...
592 my $associated_class = $self->associated_class;
593 foreach my $handle (keys %handles) {
594 my $method_to_call = $handles{$handle};
595 my $class_name = $associated_class->name;
596 my $name = "${class_name}::${handle}";
598 (!$associated_class->has_method($handle))
599 || $self->throw_error("You cannot overwrite a locally defined method ($handle) with a delegation", method_name => $handle);
602 # handles is not allowed to delegate
603 # any of these methods, as they will
604 # override the ones in your class, which
605 # is almost certainly not what you want.
607 # FIXME warn when $handle was explicitly specified, but not if the source is a regex or something
608 #cluck("Not delegating method '$handle' because it is a core method") and
609 next if $class_name->isa("Moose::Object") and $handle =~ /^BUILD|DEMOLISH$/ || Moose::Object->can($handle);
611 my $method = $self->_make_delegation_method($handle, $method_to_call);
613 $self->associated_class->add_method($method->name, $method);
617 sub remove_delegation {
619 my %handles = $self->_canonicalize_handles;
620 my $associated_class = $self->associated_class;
621 foreach my $handle (keys %handles) {
622 $self->associated_class->remove_method($handle);
626 # private methods to help delegation ...
628 sub _canonicalize_handles {
630 my $handles = $self->handles;
631 if (my $handle_type = ref($handles)) {
632 if ($handle_type eq 'HASH') {
635 elsif ($handle_type eq 'ARRAY') {
636 return map { $_ => $_ } @{$handles};
638 elsif ($handle_type eq 'Regexp') {
639 ($self->has_type_constraint)
640 || $self->throw_error("Cannot delegate methods based on a Regexp without a type constraint (isa)", data => $handles);
641 return map { ($_ => $_) }
642 grep { /$handles/ } $self->_get_delegate_method_list;
644 elsif ($handle_type eq 'CODE') {
645 return $handles->($self, $self->_find_delegate_metaclass);
648 $self->throw_error("Unable to canonicalize the 'handles' option with $handles", data => $handles);
652 Class::MOP::load_class($handles)
653 unless Class::MOP::is_class_loaded($handles);
655 my $role_meta = eval { $handles->meta };
657 $self->throw_error("Unable to canonicalize the 'handles' option with $handles because : $@", data => $handles, error => $@);
660 (blessed $role_meta && $role_meta->isa('Moose::Meta::Role'))
661 || $self->throw_error("Unable to canonicalize the 'handles' option with $handles because ->meta is not a Moose::Meta::Role", data => $handles);
663 return map { $_ => $_ } (
664 $role_meta->get_method_list,
665 $role_meta->get_required_method_list
670 sub _find_delegate_metaclass {
672 if (my $class = $self->_isa_metadata) {
673 # if the class does have
674 # a meta method, use it
675 return $class->meta if $class->can('meta');
676 # otherwise we might be
677 # dealing with a non-Moose
678 # class, and need to make
680 return Moose::Meta::Class->initialize($class);
682 elsif (my $role = $self->_does_metadata) {
683 # our role will always have
688 $self->throw_error("Cannot find delegate metaclass for attribute " . $self->name);
692 sub _get_delegate_method_list {
694 my $meta = $self->_find_delegate_metaclass;
695 if ($meta->isa('Class::MOP::Class')) {
696 return map { $_->name } # NOTE: !never! delegate &meta
697 grep { $_->package_name ne 'Moose::Object' && $_->name ne 'meta' }
698 $meta->get_all_methods;
700 elsif ($meta->isa('Moose::Meta::Role')) {
701 return $meta->get_method_list;
704 $self->throw_error("Unable to recognize the delegate metaclass '$meta'", data => $meta);
708 sub delegation_metaclass { 'Moose::Meta::Method::Delegation' }
710 sub _make_delegation_method {
711 my ( $self, $handle_name, $method_to_call ) = @_;
715 $method_body = $method_to_call
716 if 'CODE' eq ref($method_to_call);
718 return $self->delegation_metaclass->new(
719 name => $handle_name,
720 package_name => $self->associated_class->name,
722 delegate_to_method => $method_to_call,
726 sub verify_against_type_constraint {
730 return 1 if !$self->has_type_constraint;
732 my $type_constraint = $self->type_constraint;
734 $type_constraint->check($val)
735 || $self->throw_error("Attribute ("
737 . ") does not pass the type constraint because: "
738 . $type_constraint->get_message($val), data => $val, @_);
741 package Moose::Meta::Attribute::Custom::Moose;
742 sub register_implementation { 'Moose::Meta::Attribute' }
752 Moose::Meta::Attribute - The Moose attribute metaclass
756 This is a subclass of L<Class::MOP::Attribute> with Moose specific
759 For the most part, the only time you will ever encounter an
760 instance of this class is if you are doing some serious deep
761 introspection. To really understand this class, you need to refer
762 to the L<Class::MOP::Attribute> documentation.
766 =head2 Overridden methods
768 These methods override methods in L<Class::MOP::Attribute> and add
769 Moose specific features. You can safely assume though that they
770 will behave just as L<Class::MOP::Attribute> does.
780 =item B<initialize_instance_slot>
782 =item B<install_accessors>
784 =item B<remove_accessors>
786 =item B<install_delegation>
788 =item B<remove_delegation>
790 =item B<accessor_metaclass>
792 =item B<delegation_metaclass>
798 eval { $point->meta->get_attribute('x')->set_value($point, 'forty-two') };
803 I<Attribute (x) does not pass the type constraint (Int) with 'forty-two'>
805 Before setting the value, a check is made on the type constraint of
806 the attribute, if it has one, to see if the value passes it. If the
807 value fails to pass, the set operation dies with a L<throw_error>.
809 Any coercion to convert values is done before checking the type constraint.
811 To check a value against a type constraint before setting it, fetch the
812 attribute instance using L<Class::MOP::Class/find_attribute_by_name>,
813 fetch the type_constraint from the attribute using L<Moose::Meta::Attribute/type_constraint>
814 and call L<Moose::Meta::TypeConstraint/check>. See L<Moose::Cookbook::Basics::Recipe4>
819 =head2 Additional Moose features
821 Moose attributes support type-constraint checking, weak reference
822 creation and type coercion.
828 Delegates to C<associated_class> or C<Moose::Meta::Class> if there is none.
830 =item B<interpolate_class_and_new>
832 =item B<interpolate_class>
834 When called as a class method causes interpretation of the C<metaclass> and
837 =item B<clone_and_inherit_options>
839 This is to support the C<has '+foo'> feature, it clones an attribute
840 from a superclass and allows a very specific set of changes to be made
843 =item B<legal_options_for_inheritance>
845 Whitelist with options you can change. You can overload it in your custom
846 metaclass to allow your options be inheritable.
848 =item B<has_type_constraint>
850 Returns true if this meta-attribute has a type constraint.
852 =item B<type_constraint>
854 A read-only accessor for this meta-attribute's type constraint. For
855 more information on what you can do with this, see the documentation
856 for L<Moose::Meta::TypeConstraint>.
858 =item B<verify_against_type_constraint>
860 Verifies that the given value is valid under this attribute's type
861 constraint, otherwise throws an error.
865 Returns true if this meta-attribute performs delegation.
869 This returns the value which was passed into the handles option.
873 Returns true if this meta-attribute produces a weak reference.
877 Returns true if this meta-attribute is required to have a value.
881 Returns true if this meta-attribute should be initialized lazily.
883 NOTE: lazy attributes, B<must> have a C<default> or C<builder> field set.
885 =item B<is_lazy_build>
887 Returns true if this meta-attribute should be initialized lazily through
888 the builder generated by lazy_build. Using C<lazy_build =E<gt> 1> will
889 make your attribute required and lazy. In addition it will set the builder, clearer
890 and predicate options for you using the following convention.
892 #If your attribute name starts with an underscore:
893 has '_foo' => (lazy_build => 1);
895 has '_foo' => (lazy => 1, required => 1, predicate => '_has_foo', clearer => '_clear_foo', builder => '_build__foo');
897 has '_foo' => (lazy => 1, required => 1, predicate => '_has_foo', clearer => '_clear_foo', default => sub{shift->_build__foo});
899 #If your attribute name does not start with an underscore:
900 has 'foo' => (lazy_build => 1);
902 has 'foo' => (lazy => 1, required => 1, predicate => 'has_foo', clearer => 'clear_foo', builder => '_build_foo');
904 has 'foo' => (lazy => 1, required => 1, predicate => 'has_foo', clearer => 'clear_foo', default => sub{shift->_build_foo});
906 The reason for the different naming of the C<builder> is that the C<builder>
907 method is a private method while the C<clearer> and C<predicate> methods
910 NOTE: This means your class should provide a method whose name matches the value
911 of the builder part, in this case _build__foo or _build_foo.
913 =item B<should_coerce>
915 Returns true if this meta-attribute should perform type coercion.
917 =item B<should_auto_deref>
919 Returns true if this meta-attribute should perform automatic
922 NOTE: This can only be done for attributes whose type constraint is
923 either I<ArrayRef> or I<HashRef>.
927 Returns true if this meta-attribute has a trigger set.
931 This is a CODE reference which will be executed every time the
932 value of an attribute is assigned. The CODE ref will get two values,
933 the invocant and the new value. This can be used to handle I<basic>
934 bi-directional relations.
936 =item B<documentation>
938 This is a string which contains the documentation for this attribute.
939 It serves no direct purpose right now, but it might in the future
940 in some kind of automated documentation system perhaps.
942 =item B<has_documentation>
944 Returns true if this meta-attribute has any documentation.
946 =item B<applied_traits>
948 This will return the ARRAY ref of all the traits applied to this
949 attribute, or if no traits have been applied, it returns C<undef>.
951 =item B<has_applied_traits>
953 Returns true if this meta-attribute has any traits applied.
959 All complex software has bugs lurking in it, and this module is no
960 exception. If you find a bug please either email me, or add the bug
965 Stevan Little E<lt>stevan@iinteractive.comE<gt>
967 Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
969 =head1 COPYRIGHT AND LICENSE
971 Copyright 2006-2009 by Infinity Interactive, Inc.
973 L<http://www.iinteractive.com>
975 This library is free software; you can redistribute it and/or modify
976 it under the same terms as Perl itself.