File Coverage

blib/lib/Catmandu/Fix/Has.pm
Criterion Covered Total %
statement 52 52 100.0
branch 21 22 95.4
condition 9 13 69.2
subroutine 6 6 100.0
pod n/a
total 88 93 94.6


line stmt bran cond sub pod time code
1             package Catmandu::Fix::Has;
2              
3 107     107   871 use Catmandu::Sane;
  107         237  
  107         726  
4              
5             our $VERSION = '1.2020';
6              
7 107     107   1108 use Class::Method::Modifiers qw(install_modifier);
  107         260  
  107         11277  
8              
9             sub import {
10 175     175   1666 my $target = caller;
11              
12 107     107   957 my $around = do {no strict 'refs'; \&{"${target}::around"}};
  107         325  
  107         66128  
  175         4062  
  175         361  
  175         860  
13 175         458 my $fix_args = [];
14 175         428 my $fix_opts = [];
15              
16             install_modifier(
17             $target, 'around', 'has',
18             sub {
19 343     343   10270 my ($orig, $attr, %opts) = @_;
20              
21             return $orig->($attr, %opts)
22 343 100 100     1762 unless exists $opts{fix_arg} || exists $opts{fix_opt};
23              
24 323   50     2012 $opts{is} //= 'ro';
25 323   66     1542 $opts{init_arg} //= $attr;
26              
27 323         1147 my $arg = {key => $opts{init_arg}};
28              
29 323 100       1145 if ($opts{fix_arg}) {
30 268   50     1580 $opts{required} //= 1;
31 268 100       1135 $arg->{collect} = 1 if $opts{fix_arg} eq 'collect';
32 268         654 push @$fix_args, $arg;
33 268         925 delete $opts{fix_arg};
34             }
35              
36 323 100       1252 if ($opts{fix_opt}) {
37 55 100       231 $arg->{collect} = 1 if $opts{fix_opt} eq 'collect';
38 55         150 push @$fix_opts, $arg;
39 55         132 delete $opts{fix_opt};
40             }
41              
42 323         1625 $orig->($attr, %opts);
43             }
44 175         1920 );
45              
46             $around->(
47             'BUILDARGS',
48             sub {
49 661     661   397548 my $orig = shift;
50 661         1332 my $self = shift;
51              
52 661 50 66     2665 return $orig->($self, @_) unless @$fix_args || @$fix_opts;
53              
54 661         1469 my $args = {};
55              
56 661         1744 for my $arg (@$fix_args) {
57 957 100       2262 last unless @_;
58 942         2066 my $key = $arg->{key};
59 942 100       2534 if ($arg->{collect}) {
60 13         53 $args->{$key} = [splice @_, 0, @_];
61 13         32 last;
62             }
63 929         2618 $args->{$key} = shift;
64             }
65              
66 661         2657 my $orig_args = $self->$orig(@_);
67              
68 661         5452 for my $arg (@$fix_opts) {
69 319         615 my $key = $arg->{key};
70 319 100       1214 if ($arg->{collect}) {
    100          
    100          
71 59         138 $args->{$key} = $orig_args;
72 59         129 last;
73             }
74             elsif (exists $orig_args->{"-$key"}) {
75 1         4 $args->{$key} = delete $orig_args->{"-$key"};
76             }
77             elsif (exists $orig_args->{$key}) {
78 77         236 $args->{$key} = delete $orig_args->{$key};
79             }
80             }
81              
82 661         11656 $args;
83             }
84 175         63994 );
85             }
86              
87             1;
88              
89             __END__
90              
91             =pod
92              
93             =head1 NAME
94              
95             Catmandu::Fix::Has - helper class for creating Fix-es with (optional) parameters
96              
97             =head1 SYNOPSIS
98              
99             package Catmandu::Fix::foo;
100             use Moo;
101             use Catmandu::Fix::Has;
102              
103             has greeting => (fix_arg => 1); # required parameter 1
104             has message => (fix_arg => 1); # required parameter 2
105             has eol => (fix_opt => 1 , default => sub {'!'} ); # optional parameter 'eol' with default '!'
106              
107             sub fix {
108             my ($self,$data) = @_;
109              
110             print STDERR $self->greeting . ", " . $self->message . $self->eol . "\n";
111              
112             $data;
113             }
114              
115             1;
116              
117             =head1 PARAMETERS
118              
119             =over 4
120              
121             =item fix_arg
122              
123             Required argument when set to 1. The Fix containing the code fragment below needs
124             two arguments.
125              
126             use Catmandu::Fix::Has;
127              
128             has message => (fix_arg => 1); # required parameter 1
129             has number => (fix_arg => 1); # required parameter 2
130              
131             When the fix_arg is set to 'collect', then all arguments are read into an
132             array. The Fix containing the code fragment below needs at least 1 or more
133             arguments. All arguments will get collected into the C<messages> array:
134              
135             use Catmandu::Fix::Has;
136              
137             has messages => (fix_arg => 'collect'); # required parameter
138              
139             =item fix_opt
140              
141             Optional named argument when set to 1. The Fix containing the code fragment
142             below can have two optional arguments C<message: ...>, C<number: ...>:
143              
144             use Catmandu::Fix::Has;
145              
146             has message => (fix_opt => 1); # optional parameter 1
147             has number => (fix_opt => 1); # optional parameter 2
148              
149             When the fix_opt is set to 'collect', then all optional argument are read into
150             an array. The Fix containing the code fragment below needs at least 1 or more
151             arguments. All arguments will get collected into the C<options> array:
152              
153             use Catmandu::Fix::Has;
154              
155             has options => (fix_opt => 'collect'); # optional parameter
156              
157             =back
158              
159             =head1 SEE ALSO
160              
161             L<Catmandu::Fix>
162              
163             =cut
164