1 package MooseX::UndefTolerant;
9 use MooseX::UndefTolerant::Attribute;
10 use MooseX::UndefTolerant::Class;
11 use MooseX::UndefTolerant::Constructor;
16 attribute => [ 'MooseX::UndefTolerant::Attribute' ],
19 if ( $Moose::VERSION < 1.9900 ) {
20 $metaroles{class_metaroles}{constructor} = [
21 'MooseX::UndefTolerant::Constructor',
25 $metaroles{class_metaroles}{class} = [
26 'MooseX::UndefTolerant::Class',
28 $metaroles{role_metaroles} = {
29 applied_attribute => [
30 'MooseX::UndefTolerant::Attribute',
33 'MooseX::UndefTolerant::Role',
35 application_to_class => [
36 'MooseX::UndefTolerant::ApplicationToClass',
38 application_to_role => [
39 'MooseX::UndefTolerant::ApplicationToRole',
45 Moose::Exporter->setup_import_methods(%metaroles);
49 # ABSTRACT: Make your attribute(s) tolerant to undef initialization
58 use MooseX::UndefTolerant;
63 predicate => 'has_name'
66 # Meanwhile, under the city...
69 my $class = My::Class->new(name => undef);
70 $class->has_name # False!
72 Or, if you only want one attribute to have this behaviour:
77 use MooseX::UndefTolerant::Attribute;
80 traits => [ qw(MooseX::UndefTolerant::Attribute)],
83 predicate => 'has_bar'
88 Loading this module in your L<Moose> class makes initialization of your
89 attributes tolerant of undef. If you specify the value of undef to any of
90 the attributes they will not be initialized, effectively behaving as if you
91 had not provided a value at all.
93 You can also apply the 'UndefTolerant' trait to individual attributes. See
94 L<MooseX::UndefTolerant::Attribute> for details.
96 There will be no change in behaviour to any attribute with a type constraint
97 that accepts undef values (for example C<Maybe> types), as it is presumed that
98 since the type is already "undef tolerant", there is no need to avoid
99 initializing the attribute value with C<undef>.
101 As of Moose 1.9900, this module can also be used in a role, in which case all
102 of that role's attributes will be undef-tolerant.
106 I often found myself in this quandry:
118 my $foo = ... # get the param from something
120 my $class = My:Class->new(foo => $foo, bar => 123);
122 What if foo is undefined? I didn't want to change my attribute to be
123 Maybe[Str] and I still want my predicate (C<has_foo>) to work. The only
127 $class = My:Class->new(foo => $foo, bar => 123);
129 $class = My:Class->new(bar => 123);
132 Or some type of codemulch using ternary conditionals. This module allows you
133 to make your attributes more tolerant of undef so that you can keep the first
134 example: have your cake and eat it too!
138 See L<MooseX::UndefTolerant::Attribute>.
142 This extension does not currently work in immutable classes when applying the
143 trait to some (but not all) attributes in the class. This is because the
144 inlined constructor initialization code currently lives in
145 L<Moose::Meta::Class>, not L<Moose::Meta::Attribute>. The good news is that
146 this is expected to be changing shortly.
148 =head1 ACKNOWLEDGEMENTS
150 Many thanks to the crew in #moose who talked me through this module:
152 Hans Dieter Pearcey (confound)
158 Dylan Hardison (dylan)
160 Jay Shirley (jshirley)