File Coverage

blib/lib/MooseX/NotRequired.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package MooseX::NotRequired;
2              
3 1     1   27124 use 5.006;
  1         4  
  1         35  
4 1     1   6 use strict;
  1         2  
  1         90  
5 1     1   5 use warnings;
  1         16  
  1         28  
6 1     1   461 use Moose::Meta::Class;
  0            
  0            
7              
8             =head1 NAME
9              
10             MooseX::NotRequired - Make Moose sub classes with non required attributes.
11              
12             =head1 VERSION
13              
14             Version 0.11
15              
16             =cut
17              
18             our $VERSION = '0.11';
19              
20              
21             =head1 SYNOPSIS
22              
23             This module allows you to create anonymous sub classes of Moose classes with all the
24             required flags on the attributes turned off.
25              
26             package SalesOrder;
27            
28             use Moose;
29              
30             has order_number => (is => 'ro', isa => 'Str', required => 1);
31             has reference => (is => 'ro', isa => 'Str' );
32             has date_ordered => (is => 'ro', isa => 'DateTime', required => 1);
33             has total_value => (is => 'ro', isa => 'Int', required => 1);
34             has customer => (is => 'ro', isa => 'Str', required => 1);
35             has notes => (is => 'ro', isa => 'Str');
36              
37             1;
38              
39             ...
40              
41             use MooseX::NotRequired;
42              
43             my $new_class = MooseX::NotRequired::make_optional_subclass('SalesOrder');
44             my $obj = $new_class->new(); # no blow up
45             my $default = $new_class->new({ semi_required => undef }); # fine too
46             ...
47             my $second = ObjectA->new(); # blow up because required fields not present
48             my $third = ObjectA->new({ order_number => 'a', semi_required => undef });
49             # blow up because semi_required must be a string.
50              
51             This module exists because while you want to make use of Moose's awesome type constraints
52             they're sometimes a little inconvenient. Rather than throw out all your restrictions
53             because you need your class to be a little more permissive in a few scenarios, create
54             a subclass that has some of those restrictions weakened. You can of course do this manually.
55              
56             =head1 SUBROUTINES/METHODS
57              
58             =head2 make_optional_subclass
59              
60             This creates an anonymous sub class that has all the required flags on the attributes removed.
61             It also turns type constraints into Maybe constraints where possible. That generally only works
62             for simple isa's like 'Str'.
63              
64             =cut
65              
66             sub make_optional_subclass
67             {
68             my $class = shift;
69            
70             my $meta = Moose::Meta::Class->create_anon_class(superclasses => [$class], weaken => 0);
71             for my $att ($meta->get_all_attributes)
72             {
73             my $name = $att->name;
74             my $options = {};
75             if($att->is_required) {
76             $options->{required} = 0;
77             }
78             my $type = $att->{isa}; # FIXME: this is ugly
79             unless (!$type || ref $type) {
80             unless($type =~ /Maybe/)
81             {
82             my $new_type = "Maybe[$type]";
83             $options->{isa} = $new_type;
84             }
85             }
86              
87             if(%$options)
88             {
89             $meta->add_attribute("+$name", $options);
90             }
91             }
92             return $meta->name;
93             }
94              
95             =head1 AUTHOR
96              
97             Colin Newell, C<< <colin.newell at gmail.com> >>
98              
99             =head1 BUGS
100              
101             Please report any bugs or feature requests to C<bug-moosex-notrequired at rt.cpan.org>, or through
102             the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=MooseX-NotRequired>. I will be notified, and then you'll
103             automatically be notified of progress on your bug as I make changes.
104              
105              
106             =head1 SUPPORT
107              
108             You can find documentation for this module with the perldoc command.
109              
110             perldoc MooseX::NotRequired
111              
112              
113             You can also look for information at:
114              
115             =over 4
116              
117             =item * RT: CPAN's request tracker (report bugs here)
118              
119             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooseX-NotRequired>
120              
121             =item * AnnoCPAN: Annotated CPAN documentation
122              
123             L<http://annocpan.org/dist/MooseX-NotRequired>
124              
125             =item * CPAN Ratings
126              
127             L<http://cpanratings.perl.org/d/MooseX-NotRequired>
128              
129             =item * Search CPAN
130              
131             L<http://search.cpan.org/dist/MooseX-NotRequired/>
132              
133             =back
134              
135              
136             =head1 ACKNOWLEDGEMENTS
137              
138             This could wouldn't be possible without the help of doy on #moose. The cool bits were written by
139             him and the bugs/bad practice added by Colin. JJ also helped get things going again when I got stuck.
140             The Birmingham Perl Mongers also provided input which helped refine and improve the module.
141              
142             =head1 LICENSE AND COPYRIGHT
143              
144             Copyright 2011-2012 OpusVL.
145              
146             This program is free software; you can redistribute it and/or modify it
147             under the terms of either: the GNU General Public License as published
148             by the Free Software Foundation; or the Artistic License.
149              
150             See http://dev.perl.org/licenses/ for more information.
151              
152              
153             =cut
154              
155             1; # End of MooseX::NotRequired