File Coverage

blib/lib/MooseX/Meta/Parameter/Moose/Compiled.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package MooseX::Meta::Parameter::Moose::Compiled;
2              
3 1     1   2604 use Moose;
  0            
  0            
4              
5             use HTML::Template::Pro;
6             use Moose::Util::TypeConstraints;
7             use MooseX::Method::Constant;
8             use MooseX::Method::Exception;
9              
10             extends qw/MooseX::Meta::Parameter::Moose/;
11              
12             with qw/MooseX::Meta::Parameter::Compiled/;
13              
14             our $VERSION = '0.01';
15              
16             our $AUTHORITY = 'cpan:BERLE';
17              
18             my $compile_template = HTML::Template::Pro->new (scalarref => \<< 'EOF');
19             sub {
20             my $provided = $#_ >= 0;
21              
22             $_ = $_[0];
23              
24             <TMPL_VAR NAME="body">
25              
26             return $_;
27             };
28             EOF
29              
30             my $as_perl_template = HTML::Template::Pro->new (scalarref => \<< 'EOF');
31             <TMPL_IF NAME="has_default">
32             unless ($provided) {
33             <TMPL_IF NAME="has_default_coderef">
34             $_ = <TMPL_VAR NAME="default">->($self);
35             <TMPL_ELSE>
36             $_ = <TMPL_VAR NAME="default">;
37             </TMPL_IF>
38              
39             $provided = 1;
40             }
41             </TMPL_IF>
42              
43             <TMPL_IF NAME="has_constraint_or_does">
44             if ($provided) {
45             <TMPL_IF NAME="has_constraint">
46             unless (<TMPL_VAR NAME="validator">->($_)) {
47             <TMPL_IF NAME="has_coerce">
48             $_ = <TMPL_VAR NAME="constraint">->coerce ($_);
49              
50             MooseX::Method::Exception->throw ("Argument isn't a (<TMPL_VAR NAME="isa">)")
51             unless (<TMPL_VAR NAME="validator">->($_));
52             <TMPL_ELSE>
53             MooseX::Method::Exception->throw ("Argument isn't a (<TMPL_VAR NAME="isa">)");
54             </TMPL_IF>
55             }
56             </TMPL_IF>
57              
58             <TMPL_IF NAME="has_does">
59             MooseX::Method::Exception->throw ("Does not do (<TMPL_VAR NAME="does">)")
60             unless Scalar::Util::blessed ($_) && $_->can ('does') && $_->does ("<TMPL_VAR NAME="does">");
61             </TMPL_IF>
62             }
63             <TMPL_IF NAME="has_required">
64             else {
65             MooseX::Method::Exception->throw ("Must be specified");
66             }
67             </TMPL_IF>
68             <TMPL_ELSE>
69             <TMPL_IF NAME="has_required">
70             MooseX::Method::Exception->throw ("Must be specified")
71             unless ($provided);
72             </TMPL_IF>
73             </TMPL_IF>
74             EOF
75              
76             override new => sub {
77             my $self = super;
78              
79             $self->{params} = $self->_setup_params;
80              
81             return $self;
82             };
83              
84             sub validate {
85             my $self = shift;
86              
87             $self->{compiled_validator} ||= $self->compile;
88              
89             return $self->{compiled_validator}->(@_);
90             }
91              
92             sub compile {
93             my ($self) = @_;
94              
95             $compile_template->param (body => $self->as_perl);
96              
97             my $coderef = eval $compile_template->output;
98              
99             MooseX::Method::Exception->throw ("Compilation failed: $@")
100             if ($@);
101              
102             return $coderef;
103             }
104              
105             sub as_perl {
106             my ($self) = @_;
107              
108             $as_perl_template->param ($self->{params});
109              
110             return $as_perl_template->output;
111             }
112              
113             sub _setup_params {
114             my ($self) = @_;
115              
116             my $params = {
117             has_default => 0,
118             has_default_coderef => 0,
119             has_constraint_or_does => 0,
120             has_constraint => 0,
121             has_coerce => 0,
122             has_does => 0,
123             has_required => 0,
124             };
125              
126             if (defined $self->{default}) {
127             $params->{has_default} = 1;
128              
129             $params->{has_default_coderef} = (ref $self->{default} eq 'CODE');
130              
131             $params->{default} = MooseX::Method::Constant->make ($self->{default});
132             }
133              
134             if (defined $self->{type_constraint} || defined $self->{does}) {
135             $params->{has_constraint_or_does} = 1;
136              
137             if (defined $self->{type_constraint}) {
138             $params->{isa} = quotemeta $self->{isa};
139              
140             $params->{has_constraint} = 1;
141              
142             $params->{has_coerce} = $self->{coerce};
143              
144             $params->{constraint} = MooseX::Method::Constant->make ($self->{type_constraint});
145              
146             if ($self->{type_constraint}->can ('has_hand_optimized_type_constraint') && $self->{type_constraint}->has_hand_optimized_type_constraint) {
147             $params->{validator} = MooseX::Method::Constant->make ($self->{type_constraint}->hand_optimized_type_constraint);
148             } else {
149             $params->{validator} = MooseX::Method::Constant->make ($self->{type_constraint}->_compiled_type_constraint);
150             }
151              
152             $params->{has_coerce} = 1
153             if $self->{coerce};
154             }
155              
156             if (defined $self->{does}) {
157             $params->{has_does} = 1;
158              
159             $params->{does} = quotemeta $self->{does};
160             }
161             }
162              
163             $params->{has_required} = 1
164             if $self->{required};
165              
166             return $params;
167             }
168              
169             __PACKAGE__->meta->make_immutable(inline_constructor => 0);
170              
171             1;
172              
173             __END__
174              
175             =pod
176              
177             =head1 NAME
178              
179             MooseX::Meta::Parameter::Moose::Compiled - Compiled Moose parameter metaclass
180              
181             =head1 WARNING
182              
183             This API is unstable, it may change at any time. This should not
184             affect ordinary L<MooseX::Method> usage.
185              
186             =head1 METHODS
187              
188             =over 4
189              
190             =item B<validate>
191              
192             Overriden from superclass.
193              
194             =item B<as_perl>
195              
196             Returns a string of perl code that will validate an argument. Expects
197             the value to be validated to reside in $_ and that the scalar $provided
198             is present to tell if a value was provided. This is because undef is
199             an allowed provided value. Modifies $_ if coercion is set.
200              
201             =item B<compile>
202              
203             Returns a coderef that will perform the validation. Essencially a
204             wrapper around as_perl that is handy if you don't need to do any
205             inlining but still want the performance benefit. Note that the
206             validate method is overridden to use a compiled version of the
207             validator so you probably don't need to use this method yourself.
208              
209             =back
210              
211             =head1 BUGS
212              
213             Most software has bugs. This module probably isn't an exception.
214             If you find a bug please either email me, or add the bug to cpan-RT.
215              
216             =head1 AUTHOR
217              
218             Anders Nor Berle E<lt>debolaz@gmail.comE<gt>
219              
220             =head1 COPYRIGHT AND LICENSE
221              
222             Copyright 2007 by Anders Nor Berle.
223              
224             This library is free software; you can redistribute it and/or modify
225             it under the same terms as Perl itself.
226              
227             =cut
228