File Coverage

blib/lib/MooseX/Meta/Signature/Named/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::Signature::Named::Compiled;
2              
3 2     2   4965 use Moose;
  0            
  0            
4              
5             use HTML::Template::Pro;
6             use MooseX::Meta::Parameter::Moose::Compiled;
7             use MooseX::Method::Constant;
8             use MooseX::Method::Exception;
9             use Scalar::Util;
10              
11             extends qw/MooseX::Meta::Signature::Named/;
12              
13             with qw/MooseX::Meta::Signature::Compiled/;
14              
15             our $VERSION = '0.01';
16              
17             our $AUTHORITY = 'cpan:BERLE';
18              
19             my $compile_template = HTML::Template::Pro->new (scalarref => \<< 'EOF');
20             sub {
21             my @values = @_;
22              
23             <TMPL_VAR NAME="body">
24              
25             return @values;
26             }
27             EOF
28              
29             my $as_perl_template = HTML::Template::Pro->new (scalarref => \<< 'EOF');
30             my $args;
31              
32             if (ref $_[0] eq 'HASH') {
33             $args = $values[0];
34             } else {
35             $args = { @values };
36             }
37              
38             my $name;
39              
40             eval {
41             my $provided;
42             <TMPL_LOOP NAME="parameters">
43             <TMPL_IF NAME="has_inline">
44             $name = "<TMPL_VAR NAME="name">";
45              
46             $provided = exists $args->{"<TMPL_VAR NAME="name">"};
47              
48             $_ = $args->{"<TMPL_VAR NAME="name">"};
49              
50             <TMPL_VAR NAME="body">
51              
52             $args->{"<TMPL_VAR NAME="name">"} = $_;
53             <TMPL_ELSE>
54             $args->{"<TMPL_VAR NAME="name">"} = <TMPL_VAR NAME="parameter">->validate (( exists $args->{"<TMPL_VAR NAME="name">"} ? $args->{"<TMPL_VAR NAME="name">"} : ()));
55             </TMPL_IF>
56             </TMPL_LOOP>
57             };
58              
59             if ($@) {
60             if (Scalar::Util::blessed ($@) && $@->isa ('MooseX::Method::Exception')) {
61             $@->error ("Parameter ($name): " . $@->error);
62              
63             $@->rethrow;
64             } else {
65             die $@;
66             }
67             }
68              
69             @values = ($args);
70             EOF
71              
72             sub _parameter_metaclass { 'MooseX::Meta::Parameter::Moose::Compiled' }
73              
74             override new => sub {
75             my $self = super;
76              
77             $self->{params} = $self->_setup_params;
78              
79             return $self;
80             };
81              
82             sub validate {
83             my $self = shift;
84              
85             $self->{compiled_validator} ||= $self->compile;
86              
87             return $self->{compiled_validator}->(@_);
88             }
89              
90             sub compile {
91             my ($self) = @_;
92              
93             $compile_template->param (body => $self->as_perl);
94              
95             my $coderef = eval $compile_template->output;
96              
97             MooseX::Method::Exception->throw ("Compilation failed: $@")
98             if $@;
99              
100             return $coderef;
101             }
102              
103             sub as_perl {
104             my ($self) = @_;
105              
106             $as_perl_template->param ($self->{params});
107              
108             return $as_perl_template->output;
109             }
110              
111             sub _setup_params {
112             my ($self) = @_;
113              
114             my $params = {
115             parameters => [],
116             };
117              
118             for (keys %{$self->{'%!parameter_map'}}) {
119             my $parameter_params = {
120             name => quotemeta $_,
121             };
122              
123             my $parameter = $self->{'%!parameter_map'}->{$_};
124              
125             if ($parameter->does ('MooseX::Meta::Parameter::Compiled')) {
126             $parameter_params->{has_inline} = 1;
127              
128             $parameter_params->{body} = $parameter->as_perl;
129             } else {
130             $parameter_params->{parameter} = MooseX::Method::Constant->make ($parameter);
131             }
132              
133             push @{ $params->{parameters} },$parameter_params;
134             }
135              
136             return $params;
137             }
138              
139             __PACKAGE__->meta->make_immutable(inline_constructor => 0);
140              
141             1;
142              
143             __END__
144              
145             =pod
146              
147             =head1 NAME
148              
149             MooseX::Meta::Signature::Named::Compiled - Compiled named signature
150              
151             =head1 WARNING
152              
153             This API is unstable, it may change at any time. This should not
154             affect ordinary L<MooseX::Method> usage.
155              
156             =head1 SYNOPSIS
157              
158             use MooseX::Meta::Signature::Named::Compiled;
159              
160             my $validator = MooseX::Meta::Signature::Named::Compiled->new (foo => { isa => 'Int' })->compile;
161              
162             eval {
163             $validator->(foo => 42);
164             };
165              
166             =head1 METHODS
167              
168             =over 4
169              
170             =item validate
171              
172             Overriden from the superclass.
173              
174             =item compile
175              
176             Produces a validator coderef.
177              
178             =item as_perl
179              
180             Spits out most of the perl code used to produce the coderef above.
181             This is primarily used internally for inlining.
182              
183             =back
184              
185             =head1 BUGS
186              
187             Most software has bugs. This module probably isn't an exception.
188             If you find a bug please either email me, or add the bug to cpan-RT.
189              
190             =head1 AUTHOR
191              
192             Anders Nor Berle E<lt>debolaz@gmail.comE<gt>
193              
194             =head1 COPYRIGHT AND LICENSE
195              
196             Copyright 2007 by Anders Nor Berle.
197              
198             This library is free software; you can redistribute it and/or modify
199             it under the same terms as Perl itself.
200              
201             =cut
202