File Coverage

blib/lib/MooseX/UndefTolerant.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package MooseX::UndefTolerant;
2             {
3             $MooseX::UndefTolerant::VERSION = '0.19';
4             }
5             # git description: v0.18-1-g0dc4600
6              
7              
8 1     1   58783 use strict;
  1         4  
  1         35  
9 1     1   5 use warnings;
  1         2  
  1         32  
10              
11 1     1   406 use Moose 0.89 qw();
  0            
  0            
12             use Moose::Exporter;
13              
14             use MooseX::UndefTolerant::Attribute;
15             use MooseX::UndefTolerant::Class;
16             use MooseX::UndefTolerant::Constructor;
17              
18              
19             my %metaroles = (
20             class_metaroles => {
21             attribute => [ 'MooseX::UndefTolerant::Attribute' ],
22             }
23             );
24             if ( $Moose::VERSION < 1.9900 ) {
25             $metaroles{class_metaroles}{constructor} = [
26             'MooseX::UndefTolerant::Constructor',
27             ];
28             }
29             else {
30             $metaroles{class_metaroles}{class} = [
31             'MooseX::UndefTolerant::Class',
32             ];
33             $metaroles{role_metaroles} = {
34             applied_attribute => [
35             'MooseX::UndefTolerant::Attribute',
36             ],
37             role => [
38             'MooseX::UndefTolerant::Role',
39             ],
40             application_to_class => [
41             'MooseX::UndefTolerant::ApplicationToClass',
42             ],
43             application_to_role => [
44             'MooseX::UndefTolerant::ApplicationToRole',
45             ],
46             };
47             }
48              
49              
50             Moose::Exporter->setup_import_methods(%metaroles);
51              
52             1;
53              
54             # ABSTRACT: Make your attribute(s) tolerant to undef initialization
55              
56             __END__
57              
58             =pod
59              
60             =head1 NAME
61              
62             MooseX::UndefTolerant - Make your attribute(s) tolerant to undef initialization
63              
64             =head1 VERSION
65              
66             version 0.19
67              
68             =head1 SYNOPSIS
69              
70             package My::Class;
71              
72             use Moose;
73             use MooseX::UndefTolerant;
74              
75             has 'name' => (
76             is => 'ro',
77             isa => 'Str',
78             predicate => 'has_name'
79             );
80              
81             # Meanwhile, under the city...
82              
83             # Doesn't explode
84             my $class = My::Class->new(name => undef);
85             $class->has_name # False!
86              
87             Or, if you only want one attribute to have this behaviour:
88              
89             package My:Class;
90             use Moose;
91              
92             use MooseX::UndefTolerant::Attribute;
93              
94             has 'bar' => (
95             traits => [ qw(MooseX::UndefTolerant::Attribute)],
96             is => 'ro',
97             isa => 'Num',
98             predicate => 'has_bar'
99             );
100              
101             =head1 DESCRIPTION
102              
103             Loading this module in your L<Moose> class makes initialization of your
104             attributes tolerant of undef. If you specify the value of undef to any of
105             the attributes they will not be initialized, effectively behaving as if you
106             had not provided a value at all.
107              
108             You can also apply the 'UndefTolerant' trait to individual attributes. See
109             L<MooseX::UndefTolerant::Attribute> for details.
110              
111             There will be no change in behaviour to any attribute with a type constraint
112             that accepts undef values (for example C<Maybe> types), as it is presumed that
113             since the type is already "undef tolerant", there is no need to avoid
114             initializing the attribute value with C<undef>.
115              
116             As of Moose 1.9900, this module can also be used in a role, in which case all
117             of that role's attributes will be undef-tolerant.
118              
119             =head1 MOTIVATION
120              
121             I often found myself in this quandry:
122              
123             package My:Class;
124             use Moose;
125              
126             has 'foo' => (
127             is => 'ro',
128             isa => 'Str',
129             );
130              
131             # ... then
132              
133             my $foo = ... # get the param from something
134              
135             my $class = My:Class->new(foo => $foo, bar => 123);
136              
137             What if foo is undefined? I didn't want to change my attribute to be
138             Maybe[Str] and I still want my predicate (C<has_foo>) to work. The only
139             real solution was:
140              
141             if(defined($foo)) {
142             $class = My:Class->new(foo => $foo, bar => 123);
143             } else {
144             $class = My:Class->new(bar => 123);
145             }
146              
147             Or some type of codemulch using ternary conditionals. This module allows you
148             to make your attributes more tolerant of undef so that you can keep the first
149             example: have your cake and eat it too!
150              
151             =head1 PER ATTRIBUTE
152              
153             See L<MooseX::UndefTolerant::Attribute>.
154              
155             =head1 CAVEATS
156              
157             This extension does not currently work in immutable classes when applying the
158             trait to some (but not all) attributes in the class. This is because the
159             inlined constructor initialization code currently lives in
160             L<Moose::Meta::Class>, not L<Moose::Meta::Attribute>. The good news is that
161             this is expected to be changing shortly.
162              
163             =head1 ACKNOWLEDGEMENTS
164              
165             Many thanks to the crew in #moose who talked me through this module:
166              
167             Hans Dieter Pearcey (confound)
168              
169             Jesse Luehrs (doy)
170              
171             Tomas Doran (t0m)
172              
173             Dylan Hardison (dylan)
174              
175             Jay Shirley (jshirley)
176              
177             Mike Eldridge (diz)
178              
179             =head1 AUTHOR
180              
181             Cory G Watson <gphat at cpan.org>
182              
183             =head1 COPYRIGHT AND LICENSE
184              
185             This software is copyright (c) 2011 by Cory G Watson.
186              
187             This is free software; you can redistribute it and/or modify it under
188             the same terms as the Perl 5 programming language system itself.
189              
190             =cut