File Coverage

blib/lib/Venus/Coercion.pm
Criterion Covered Total %
statement 47 50 94.0
branch 8 12 66.6
condition 2 3 66.6
subroutine 13 14 92.8
pod 7 9 77.7
total 77 88 87.5


line stmt bran cond sub pod time code
1             package Venus::Coercion;
2              
3 7     7   176 use 5.018;
  7         26  
4              
5 7     7   55 use strict;
  7         12  
  7         167  
6 7     7   42 use warnings;
  7         15  
  7         223  
7              
8 7     7   54 use Venus::Class 'attr', 'base', 'with';
  7         14  
  7         59  
9              
10 7     7   3886 use Venus::Check;
  7         26  
  7         42  
11              
12             base 'Venus::Kind::Utility';
13              
14             with 'Venus::Role::Buildable';
15              
16             # ATTRIBUTES
17              
18             attr 'on_eval';
19              
20             # BUILDERS
21              
22             sub build_arg {
23 0     0 0 0 my ($self, $data) = @_;
24              
25             return {
26 0 0       0 on_eval => ref $data eq 'ARRAY' ? $data : [$data],
27             };
28             }
29              
30             sub build_args {
31 301     301 0 589 my ($self, $data) = @_;
32              
33 301 50       940 $data->{on_eval} = [] if !$data->{on_eval};
34              
35 301         701 return $data;
36             }
37              
38             # METHODS
39              
40             sub accept {
41 240     240 1 518 my ($self, $name, @args) = @_;
42              
43 240 50       464 if (!$name) {
44 0         0 return $self;
45             }
46 240 100       459 if ($self->check->can($name)) {
47 239         478 $self->check->accept($name, @args);
48             }
49             else {
50 1         4 $self->check->identity($name, @args);
51             }
52 240         687 return $self;
53             }
54              
55             sub check {
56 1298     1298 1 2470 my ($self, @args) = @_;
57              
58 1298 100       2627 $self->{check} = $args[0] if @args;
59              
60 1298   66     4712 return $self->{check} ||= Venus::Check->new;
61             }
62              
63             sub clear {
64 2     2 1 8 my ($self) = @_;
65              
66 2         7 @{$self->on_eval} = ();
  2         9  
67              
68 2         8 $self->check->clear;
69              
70 2         12 return $self;
71             }
72              
73             sub format {
74 239     239 1 485 my ($self, @code) = @_;
75              
76 239         313 push @{$self->on_eval}, @code;
  239         502  
77              
78 239         604 return $self;
79             }
80              
81             sub eval {
82 756     756 1 2050 my ($self, $data) = @_;
83              
84 756 100       1457 if (!$self->check->eval($data)) {
85 642         2493 return $data;
86             }
87              
88 114         225 for my $callback (@{$self->on_eval}) {
  114         378  
89 61         122 local $_ = $data;
90 61         488 $data = $self->$callback($data);
91             }
92              
93 114         586 return $data;
94             }
95              
96             sub evaler {
97 2     2 1 6 my ($self) = @_;
98              
99 2         20 return $self->defer('eval');
100             }
101              
102             sub result {
103 748     748 1 1254 my ($self, $data) = @_;
104              
105 748         1456 return $self->eval($data);
106             }
107              
108             1;
109              
110              
111              
112             =head1 NAME
113              
114             Venus::Coercion - Coercion Class
115              
116             =cut
117              
118             =head1 ABSTRACT
119              
120             Coercion Class for Perl 5
121              
122             =cut
123              
124             =head1 SYNOPSIS
125              
126             package main;
127              
128             use Venus::Coercion;
129              
130             my $coercion = Venus::Coercion->new;
131              
132             # $coercion->accept('float');
133              
134             # $coercion->format(sub{sprintf '%.2f', $_});
135              
136             # $coercion->result(123.456);
137              
138             # 123.46
139              
140             =cut
141              
142             =head1 DESCRIPTION
143              
144             This package provides a mechanism for evaluating type coercions on data.
145             Built-in type coercions are handled via L.
146              
147             =cut
148              
149             =head1 INHERITS
150              
151             This package inherits behaviors from:
152              
153             L
154              
155             =cut
156              
157             =head1 INTEGRATES
158              
159             This package integrates behaviors from:
160              
161             L
162              
163             =cut
164              
165             =head1 METHODS
166              
167             This package provides the following methods:
168              
169             =cut
170              
171             =head2 accept
172              
173             accept(string $name, any @args) (Venus::Coercion)
174              
175             The accept method registers a condition via L based on the arguments
176             provided. The built-in types are defined as methods in L.
177              
178             I>
179              
180             =over 4
181              
182             =item accept example 1
183              
184             # given: synopsis
185              
186             package main;
187              
188             $coercion = $coercion->accept('float');
189              
190             # bless(..., "Venus::Coercion")
191              
192             # $coercion->result;
193              
194             # undef
195              
196             # $coercion->result(1.01);
197              
198             # 1.01
199              
200             =back
201              
202             =over 4
203              
204             =item accept example 2
205              
206             # given: synopsis
207              
208             package main;
209              
210             $coercion = $coercion->accept('number');
211              
212             # bless(..., "Venus::Coercion")
213              
214             # $coercion->result(1.01);
215              
216             # 1.01
217              
218             # $coercion->result(1_01);
219              
220             # 101
221              
222             =back
223              
224             =over 4
225              
226             =item accept example 3
227              
228             # given: synopsis
229              
230             package Example1;
231              
232             sub new {
233             bless {};
234             }
235              
236             package Example2;
237              
238             sub new {
239             bless {};
240             }
241              
242             package main;
243              
244             $coercion = $coercion->accept('object');
245              
246             # bless(..., "Venus::Coercion")
247              
248             # $coercion->result;
249              
250             # undef
251              
252             # $coercion->result(qr//);
253              
254             # qr//
255              
256             # $coercion->result(Example1->new);
257              
258             # bless(..., "Example1")
259              
260             # $coercion->result(Example2->new);
261              
262             # bless(..., "Example2")
263              
264             =back
265              
266             =over 4
267              
268             =item accept example 4
269              
270             # given: synopsis
271              
272             package Example1;
273              
274             sub new {
275             bless {};
276             }
277              
278             package Example2;
279              
280             sub new {
281             bless {};
282             }
283              
284             package main;
285              
286             $coercion = $coercion->accept('Example1');
287              
288             # bless(..., "Venus::Coercion")
289              
290             # $coercion->result;
291              
292             # undef
293              
294             # $coercion->result(qr//);
295              
296             # qr//
297              
298             # $coercion->result(Example1->new);
299              
300             # bless(..., "Example1")
301              
302             # $coercion->result(Example2->new);
303              
304             # bless(..., "Example2")
305              
306             =back
307              
308             =cut
309              
310             =head2 check
311              
312             check(Venus::Check $data) (Venus::Check)
313              
314             The check method gets or sets the L object used for performing
315             runtime data type validation.
316              
317             I>
318              
319             =over 4
320              
321             =item check example 1
322              
323             # given: synopsis
324              
325             package main;
326              
327             my $check = $coercion->check(Venus::Check->new);
328              
329             # bless(..., 'Venus::Check')
330              
331             =back
332              
333             =over 4
334              
335             =item check example 2
336              
337             # given: synopsis
338              
339             package main;
340              
341             $coercion->check(Venus::Check->new);
342              
343             my $check = $coercion->check;
344              
345             # bless(..., 'Venus::Check')
346              
347             =back
348              
349             =cut
350              
351             =head2 clear
352              
353             clear() (Venus::Coercion)
354              
355             The clear method resets the L attributes and returns the invocant.
356              
357             I>
358              
359             =over 4
360              
361             =item clear example 1
362              
363             # given: synopsis
364              
365             package main;
366              
367             $coercion->accept('string');
368              
369             $coercion = $coercion->clear;
370              
371             # bless(..., "Venus::Coercion")
372              
373             =back
374              
375             =cut
376              
377             =head2 eval
378              
379             eval(any $data) (boolean)
380              
381             The eval method dispatches to the L object as well as evaluating any
382             custom conditions, and returns the coerced value if all conditions pass, and
383             the original value if any condition fails.
384              
385             I>
386              
387             =over 4
388              
389             =item eval example 1
390              
391             # given: synopsis
392              
393             package main;
394              
395             use Venus::Float;
396              
397             $coercion->accept('float');
398              
399             $coercion->format(sub{Venus::Float->new($_)});
400              
401             my $eval = $coercion->eval('1.00');
402              
403             # bless(..., "Venus::Float")
404              
405             =back
406              
407             =over 4
408              
409             =item eval example 2
410              
411             # given: synopsis
412              
413             package main;
414              
415             use Venus::Float;
416              
417             $coercion->accept('float');
418              
419             $coercion->format(sub{Venus::Float->new($_)});
420              
421             my $eval = $coercion->eval(1_00);
422              
423             # 100
424              
425             =back
426              
427             =cut
428              
429             =head2 evaler
430              
431             evaler(any @args) (coderef)
432              
433             The evaler method returns a coderef which calls the L method with the
434             invocant when called.
435              
436             I>
437              
438             =over 4
439              
440             =item evaler example 1
441              
442             # given: synopsis
443              
444             package main;
445              
446             my $evaler = $coercion->evaler;
447              
448             # sub{...}
449              
450             # my $result = $evaler->();
451              
452             # undef
453              
454             =back
455              
456             =over 4
457              
458             =item evaler example 2
459              
460             # given: synopsis
461              
462             package main;
463              
464             my $evaler = $coercion->accept('any')->evaler;
465              
466             # sub{...}
467              
468             # my $result = $evaler->('hello');
469              
470             # "hello"
471              
472             =back
473              
474             =cut
475              
476             =head2 format
477              
478             format(coderef $code) (Venus::Coercion)
479              
480             The format method registers a custom (not built-in) coercion condition and
481             returns the invocant.
482              
483             I>
484              
485             =over 4
486              
487             =item format example 1
488              
489             # given: synopsis
490              
491             package main;
492              
493             $coercion->accept('either', 'float', 'number');
494              
495             my $format = $coercion->format(sub {
496             int $_
497             });
498              
499             # bless(.., "Venus::Coercion")
500              
501             =back
502              
503             =cut
504              
505             =head2 result
506              
507             result(any $data) (boolean)
508              
509             The result method dispatches to the L method and returns the result.
510              
511             I>
512              
513             =over 4
514              
515             =item result example 1
516              
517             # given: synopsis
518              
519             package main;
520              
521             $coercion->accept('float');
522              
523             $coercion->format(sub{int $_});
524              
525             my $result = $coercion->result('1.00');
526              
527             # 1
528              
529             =back
530              
531             =over 4
532              
533             =item result example 2
534              
535             # given: synopsis
536              
537             package main;
538              
539             $coercion->accept('float');
540              
541             $coercion->format(sub{int $_});
542              
543             my $result = $coercion->result('0.99');
544              
545             # 0
546              
547             =back
548              
549             =cut
550              
551             =head1 AUTHORS
552              
553             Awncorp, C
554              
555             =cut
556              
557             =head1 LICENSE
558              
559             Copyright (C) 2000, Awncorp, C.
560              
561             This program is free software, you can redistribute it and/or modify it under
562             the terms of the Apache license version 2.0.
563              
564             =cut