File Coverage

blib/lib/Eve/Support.pm
Criterion Covered Total %
statement 63 63 100.0
branch 15 16 93.7
condition n/a
subroutine 14 14 100.0
pod 5 5 100.0
total 97 98 98.9


line stmt bran cond sub pod time code
1             package Eve::Support;
2              
3 31     31   9194 use strict;
  31         134  
  31         1022  
4 31     31   163 use warnings;
  31         68  
  31         749  
5              
6 31     31   3623 use Contextual::Return;
  31         44870  
  31         168  
7 31     31   33445 use PadWalker ();
  31         31576  
  31         748  
8 31     31   33544 use Tie::IxHash;
  31         164982  
  31         1239  
9              
10 31     31   16458 use Eve::Exception;
  31         124  
  31         30455  
11              
12             =head1 NAME
13              
14             B - an utility class that houses various helper functions
15              
16             =head1 SYNOPSIS
17              
18             use Eve::Support;
19              
20             Eve::Support::arguments(\%arg_hash,
21             my $required_argument, my $optional_argument = 'default value'
22             );
23              
24             =head1 SUBROUTINES
25              
26             =head2 B
27              
28             The C method makes it easier to specify a list of required
29             and optional arguments in any other method. It can be used in both
30             class method calls and usual subroutine calls.
31              
32             Here is an example in a usual subroutine:
33              
34             sub usual_subroutine {
35             my (%arg_hash) = @_;
36             Eve::Support::arguments(\%arg_hash,
37             my ($required_argument, $another_required_argument),
38             my ($optional_argument, $optional_empty_argument) = (1, \undef)
39             );
40             }
41              
42             The same may be done in a class method call:
43              
44             sub class_method {
45             my ($self, %arg_hash) = @_;
46             Eve::Support::arguments(\%arg_hash,
47             my ($required_argument, $another_required_argument),
48             my ($optional_argument, $optional_empty_argument)
49             = ('default', \undef)
50             );
51             }
52              
53             If the function is called in the RVALUE context it skips the
54             redundancy check and returns the rest of arguments that have not been
55             processed as a hash reference.
56              
57             sub foo {
58             my (%arg_hash) = @_;
59             my $rest_hash = Eve::Support::arguments(
60             \%arg_hash, my $bar);
61              
62             return $rest_hash;
63             }
64              
65             Here the call C 1, baz => 2, bad => 3)> will return the
66             hash C<{'baz' => 2, 'bad' => 3}>.
67              
68             =head3 Arguments
69              
70             =over 4
71              
72             =item C<\%arg_hash>
73              
74             A reference to a hash of arguments that has been passed into the
75             current method.
76              
77             =item C<@variable_list>
78              
79             A list of variables that have to be filled by values from the
80             incoming C<\%arg_hash>.
81              
82             =back
83              
84             =head3 Throws
85              
86             =over 4
87              
88             =item C
89              
90             could not get a variable for a named argument, an argument is required
91             or an argument is redundant.
92              
93             =back
94              
95             =cut
96              
97             sub arguments : lvalue {
98 1114     1114 1 14339 my $arg_hash = shift;
99              
100 1114         2286 foreach my $var (@_) {
101 3041         9033 my $name = PadWalker::var_name(1, \$var);
102 3041 100       7275 if (not defined($name)) {
103 1         9 Eve::Error::Attribute->throw(
104             message => 'Could not get a variable for a named argument');
105             }
106              
107 3040         10641 $name =~ s/^\$//;
108              
109 3040 100       8524 if (exists($arg_hash->{$name})) {
110 3012         5546 $var = $arg_hash->{$name};
111 3012         8929 delete($arg_hash->{$name});
112             } else {
113 28 100       79 if (defined($var)) {
114 27 100       113 if ($var eq \undef) {
115             # Work around default undef value
116 16         49 $var = undef;
117             } else {
118             # Leave the value that was assigned
119             }
120             } else {
121 1         7 Eve::Error::Attribute->throw(
122             message => 'Required argument: '.$name);
123             }
124             }
125             }
126              
127             NVALUE {
128 1108     1108   61524 my @keys = keys(%$arg_hash);
129 1108 100       4257 if (@keys) {
130 2         30 Eve::Error::Attribute->throw(
131             message => 'Redundant argument(s): '.join(', ', sort(@keys)));
132             }
133             }
134             RVALUE {
135 4     4   227 $arg_hash;
136             }
137 1112         11976 }
138              
139             =head2 B
140              
141             =head3 Arguments
142              
143             =over 4
144              
145             =item C
146              
147             =back
148              
149             =head3 Returns
150              
151             A list containing only unique elements of the passed list.
152              
153             =cut
154              
155             sub unique {
156 3     3 1 942 my %arg_hash = @_;
157 3         11 Eve::Support::arguments(\%arg_hash, my $list);
158              
159 3         32 my $unique_list = [];
160 3         7 my $seen_hash = {};
161 3         4 for my $item (@{$list}) {
  3         9  
162 12 100       32 if (not exists $seen_hash->{$item}) {
163 10         12 push(@{$unique_list}, $item);
  10         18  
164 10         27 $seen_hash->{$item} = 1;
165             }
166             }
167              
168 3         22 return $unique_list;
169             }
170              
171             =head2 B
172              
173             =head3 Arguments
174              
175             =over 4
176              
177             =item C
178              
179             =item C
180              
181             =back
182              
183             =head3 Returns
184              
185             A filehandle.
186              
187             =head3 Throws
188              
189             =over 4
190              
191             =item C
192              
193             in case of a file open error.
194              
195             =back
196              
197             =cut
198              
199             sub open {
200 2     2 1 2039 my %arg_hash = @_;
201 2         10 Eve::Support::arguments(\%arg_hash, my ($mode, $file));
202              
203 2 50   1   68 open(my $filehandle, $mode, $file) or
  1         13  
  1         2  
  1         8  
204             Eve::Exception::InputOutput->throw(
205             message => "Error occured when opening the file '$file': ".$!);
206              
207 2         1586 return $filehandle;
208             }
209              
210             =head2 B
211              
212             =head3 Arguments
213              
214             Key-value pair list.
215              
216             =head3 Returns
217              
218             A hash tied to L.
219              
220             =cut
221              
222             sub indexed_hash {
223 5     5 1 2396 tie(my %hash, 'Tie::IxHash', @_);
224              
225 5         310 return \%hash;
226             }
227              
228             =head2 B
229              
230             =head3 Arguments
231              
232             A string.
233              
234             =head3 Returns
235              
236             Trimmed string.
237              
238             =head3 Throws
239              
240             =over 4
241              
242             =item C
243              
244             if the triming value is undefined.
245              
246             =back
247              
248             =cut
249              
250             sub trim {
251 5     5 1 881 my %arg_hash = @_;
252 5         13 Eve::Support::arguments(\%arg_hash, my $string);
253              
254 5 100       55 if (not defined $string) {
255 1         19 Eve::Error::Value->throw(
256             message => 'Trimming value must be defined');
257             }
258              
259 4         12 $string =~ s/^\s+//;
260 4         13 $string =~ s/\s+$//;
261              
262 4         22 return $string;
263             }
264              
265             =head1 SEE ALSO
266              
267             =over 4
268              
269             =item L
270              
271             =back
272              
273             =head1 LICENSE AND COPYRIGHT
274              
275             Copyright 2012 Igor Zinovyev.
276              
277             This program is free software; you can redistribute it and/or modify it
278             under the terms of either: the GNU General Public License as published
279             by the Free Software Foundation; or the Artistic License.
280              
281             See http://dev.perl.org/licenses/ for more information.
282              
283              
284             =head1 AUTHOR
285              
286             =over 4
287              
288             =item L
289              
290             =back
291              
292             =cut
293              
294             1;