File Coverage

blib/lib/MooseX/NotRequired.pm
Criterion Covered Total %
statement 26 26 100.0
branch 8 8 100.0
condition 2 3 66.6
subroutine 5 5 100.0
pod 1 1 100.0
total 42 43 97.6


line stmt bran cond sub pod time code
1             package MooseX::NotRequired;
2              
3 4     4   1198393 use 5.006;
  4         26  
4 4     4   18 use strict;
  4         7  
  4         68  
5 4     4   18 use warnings;
  4         6  
  4         94  
6 4     4   1026 use Moose::Meta::Class;
  4         250926  
  4         885  
7              
8             =head1 NAME
9              
10             MooseX::NotRequired - Make Moose sub classes with non required attributes.
11              
12             =head1 VERSION
13              
14             Version 0.12
15              
16             =cut
17              
18             our $VERSION = '0.12';
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 2     2 1 598015 my $class = shift;
69            
70 2         20 my $meta = Moose::Meta::Class->create_anon_class(superclasses => [$class], weaken => 0);
71 2         4815 for my $att ($meta->get_all_attributes)
72             {
73 11         40066 my $name = $att->name;
74 11         23 my $options = {};
75 11 100       350 if($att->is_required) {
76 5         48 $options->{required} = 0;
77             }
78 11         57 my $type = $att->{isa}; # FIXME: this is ugly
79 11 100 66     57 unless (!$type || ref $type) {
80 10 100       29 unless($type =~ /Maybe/)
81             {
82 9         24 my $new_type = "Maybe[$type]";
83 9         21 $options->{isa} = $new_type;
84             }
85             }
86              
87 11 100       27 if(%$options)
88             {
89 9         50 $meta->add_attribute("+$name", $options);
90             }
91             }
92 2         17540 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 L<https://github.com/colinnewell/MooseX-NotRequired/issues>. I will be
102             notified, and then you'll automatically be notified of progress on your bug as I make changes.
103              
104              
105             =head1 SUPPORT
106              
107             You can find documentation for this module with the perldoc command.
108              
109             perldoc MooseX::NotRequired
110              
111              
112             You can also look for information at:
113              
114             =over 4
115              
116             =item * Github request tracker (report bugs here)
117              
118             L<https://github.com/colinnewell/MooseX-NotRequired/issues>
119              
120             =item * Github source code repository
121              
122             L<https://github.com/colinnewell/MooseX-NotRequired/>
123              
124             =item * AnnoCPAN: Annotated CPAN documentation
125              
126             L<http://annocpan.org/dist/MooseX-NotRequired>
127              
128             =item * CPAN Ratings
129              
130             L<http://cpanratings.perl.org/d/MooseX-NotRequired>
131              
132             =item * Search CPAN
133              
134             L<http://search.cpan.org/dist/MooseX-NotRequired/>
135              
136             =back
137              
138              
139             =head1 ACKNOWLEDGEMENTS
140              
141             This could wouldn't be possible without the help of doy on #moose. The cool bits were written by
142             him and the bugs/bad practice added by Colin. JJ also helped get things going again when I got stuck.
143             The Birmingham Perl Mongers also provided input which helped refine and improve the module.
144              
145             =head1 LICENSE AND COPYRIGHT
146              
147             Copyright 2011-2015 OpusVL.
148              
149             This program is free software; you can redistribute it and/or modify it
150             under the terms of either: the GNU General Public License as published
151             by the Free Software Foundation; or the Artistic License.
152              
153             See http://dev.perl.org/licenses/ for more information.
154              
155              
156             =cut
157              
158             1; # End of MooseX::NotRequired