File Coverage

blib/lib/Acme/Pythonic/Functions.pm
Criterion Covered Total %
statement 14 212 6.6
branch 0 100 0.0
condition 0 24 0.0
subroutine 5 31 16.1
pod 24 26 92.3
total 43 393 10.9


line stmt bran cond sub pod time code
1             package Acme::Pythonic::Functions;
2              
3 1     1   14752 use 5;
  1         2  
4 1     1   6 use warnings;
  1         1  
  1         44  
5 1     1   7 use strict;
  1         7  
  1         40  
6              
7             #######################################################################
8             # Acme::Pythonic::Functions is Copyright (C) 2009-2017, Hauke Lubenow.
9             #
10             # This module is free software; you can redistribute it and/or modify it
11             # under the same terms as Perl 5.14.2.
12             # For more details, see the full text of the licenses in the directory
13             # LICENSES. The full text of the licenses can also be found in the
14             # documents 'perldoc perlgpl' and 'perldoc perlartistic' of the official
15             # Perl 5.14.2-distribution. In case of any contradictions, these
16             # 'perldoc'-texts are decisive.
17             #
18             # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
19             # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
20             # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
21             # FOR MORE DETAILS, SEE THE FULL TEXTS OF THE LICENSES IN THE DIRECTORY
22             # LICENSES AND IN THE 'PERLDOC'-TEXTS MENTIONED ABOVE.
23             #######################################################################
24              
25 1     1   5 use Carp;
  1         1  
  1         82  
26              
27 1     1   7 use Exporter;
  1         9  
  1         1792  
28              
29             our ($VERSION, @ISA, @EXPORT);
30             @ISA = qw(Exporter);
31              
32             $VERSION = 0.40;
33              
34             @EXPORT = qw(append endswith extend has_key insert isdigit isin isdir isfile len listdir lstrip lstrip2 oslistdir osname pyprint readfile remove replace rstrip rstrip2 startswith strip writefile);
35              
36             # Internal Functions
37              
38             sub checkArgs {
39              
40 0     0 0   my ($nr, @vals) = @_;
41              
42 0           my $lenvals = @vals;
43              
44 0 0         if($lenvals != $nr) {
45              
46 0           my $name = (caller 1)[3];
47 0           my @temp = split("::", $name);
48 0           $name = pop(@temp) . "()";
49              
50 0           my $arg = "arguments";
51              
52 0 0         if($nr == 1) {
53 0           $arg = "argument";
54             }
55              
56 0           croak "Error: Function '$name' takes exactly $nr $arg ($lenvals given),";
57             }
58             }
59              
60             # print-Replacement-Function
61              
62             sub pyprint {
63 0 0   0 1   if ($#_ == -1) {
64 0           print "\n";
65 0           return;
66             }
67 0 0         if ($#_ == 0) {
68 0           print ("$_[0]\n");
69 0           return;
70             }
71             # Print the array similar to a Python-list:
72 0           my @a = @_;
73 0           my $s;
74             my $i;
75 0           print "[";
76 0           for $i (0 .. $#a) {
77             # Put quotation-marks around strings, but not around references:
78 0 0 0       if ($a[$i] =~ /[^0-9-]/ && ref($a[$i]) eq "") {
79 0           print "\"$a[$i]\"";
80             } else {
81 0           print $a[$i];
82             }
83 0 0         if ($i != $#a) {
84 0           print ", ";
85             } else {
86 0           print "]\n";
87             }
88             }
89             }
90              
91             # String-Functions
92              
93             sub endswith {
94              
95 0     0 1   checkArgs(2, @_);
96              
97 0 0         if ($_[0] =~ /\Q$_[1]\E$/) {
98 0           return 1;
99             }
100             else {
101 0           return 0;
102             }
103             }
104              
105              
106             sub lstrip {
107              
108 0     0 1   checkArgs(1, @_);
109              
110 0           my $a = $_[0];
111              
112 0           $a =~ s/^\s+//;
113              
114 0           return $a;
115             }
116              
117              
118             sub isdigit {
119              
120 0     0 1   checkArgs(1, @_);
121              
122 0 0         if($_[0] =~ /\D/) {
123 0           return 0;
124             }
125             else {
126 0           return 1;
127             }
128             }
129              
130              
131             sub lstrip2 {
132              
133 0     0 1   checkArgs(2, @_);
134              
135 0           my ($a, $b) = @_;
136              
137 0 0         if($a !~ /^\Q$b\E/) {
138 0           return $a;
139             }
140              
141 0 0         if (length($b) > length($a)) {
142 0           return $a;
143             }
144              
145 0           return substr($a, length($b));
146             }
147              
148              
149             sub replace {
150              
151 0     0 1   my $nrargs = @_;
152              
153 0 0 0       if($nrargs < 3 || $nrargs > 4) {
154 0           croak "Error: Function 'replace()' takes either 3 or 4 arguments ($nrargs given),";
155             }
156              
157 0           my $count = 0;
158              
159 0 0         if($nrargs == 4) {
160 0           $count = pop(@_);
161             }
162              
163 0 0         unless (isdigit($count)) {
164 0           carp "Warning: Argument 4 of function 'replace()' should be a number; assuming 0,";
165 0           $count = 0;
166             }
167              
168 0           my ($all, $old, $new) = @_;
169              
170 0 0         if ($count == 0) {
171 0           $all =~ s/\Q$old\E/$new/g;
172 0           return $all;
173             }
174              
175 0           for (1 .. $count) {
176 0           $all =~ s/\Q$old\E/$new/;
177             }
178              
179 0           return $all;
180             }
181              
182              
183             sub rstrip {
184              
185 0     0 1   checkArgs(1, @_);
186              
187 0           my $a = $_[0];
188              
189 0           $a =~ s/\s+$//;
190              
191 0           return $a;
192             }
193              
194              
195             sub rstrip2 {
196              
197 0     0 1   checkArgs(2, @_);
198              
199 0           my ($a, $b) = @_;
200              
201 0 0         if($a !~ /\Q$b\E$/) {
202 0           return $a;
203             }
204              
205 0 0         if (length($b) > length($a)) {
206 0           return $a;
207             }
208              
209 0           return substr($a, 0, length($a) - length($b));
210             }
211              
212              
213             sub startswith {
214              
215 0     0 1   checkArgs(2, @_);
216              
217 0 0         if ($_[0] =~ /^\Q$_[1]\E/) {
218 0           return 1;
219             }
220             else {
221 0           return 0;
222             }
223             }
224              
225              
226             sub strip {
227              
228 0     0 1   checkArgs(1, @_);
229              
230 0           my $a = $_[0];
231              
232 0           $a =~ s/^\s+//;
233 0           $a =~ s/\s+$//;
234              
235 0           return $a;
236             }
237              
238             # List-Functions
239              
240             sub append {
241              
242 0 0   0 1   if($#_ < 1) {
243 0           carp "Warning: Not enough arguments for 'append()',";
244             }
245              
246 0           return @_;
247             }
248              
249             sub extend {
250              
251 0 0   0 1   if($#_ < 1) {
252 0           carp "Warning: Not enough arguments for 'extend()',";
253             }
254              
255 0           return @_;
256             }
257              
258              
259             sub insert {
260              
261 0 0   0 1   if($#_ < 1) {
262 0           carp "Warning: Not enough arguments for 'insert()'; nothing inserted,";
263 0           return @_;
264             }
265              
266 0           my $a = pop;
267 0           my $b = pop;
268              
269 0 0         if($b =~ /\D/) {
270 0           carp "Warning: Second argument for 'insert()' must be a number; nothing inserted,";
271 0           return @_;
272             }
273            
274 0           my @c = @_;
275              
276 0 0         if ($b > $#c + 1) {
277 0           carp "Warning: Position for 'insert()' beyond list; nothing inserted,";
278 0           return @_;
279             }
280              
281 0           splice(@c, $b, 0, $a);
282              
283 0           return @c;
284             }
285              
286              
287             sub lenlist {
288 0     0 0   return $#_ + 1;
289             }
290              
291              
292             sub remove {
293              
294 0 0   0 1   if($#_ < 1) {
295 0           carp "Warning: Not enough arguments for 'remove()',";
296 0           return @_;
297             }
298              
299 0           my $a = pop;
300              
301 0           my @b = @_;
302 0           my $i;
303 0           my $x = 0;
304              
305 0           for $i (0 .. $#_) {
306 0 0         if ($_[$i] eq $a) {
307 0           splice(@b, $i, 1);
308 0           $x = 1;
309 0           last;
310             }
311             }
312              
313 0 0         unless($x) {
314 0           carp "Warning: Element to remove not found in list; nothing removed,";
315             }
316              
317 0           return @b;
318             }
319              
320             # Hash-Functions
321              
322             sub has_key {
323              
324 0 0 0 0 1   if($#_ < 2 || $#_ % 2) {
325 0           croak "Error: Unsuitable arguments to 'has_key()',";
326             }
327              
328 0           my $key = pop;
329 0           my %hash = @_;
330              
331 0 0         if (exists $hash{$key}) {
332 0           return 1;
333             }
334             else {
335 0           return 0;
336             }
337             }
338              
339              
340             # Functions for several datatypes
341              
342             sub isin {
343              
344 0     0 1   my $lenarg = @_;
345              
346 0 0         if ($lenarg < 3) {
347 0           croak "Error: 'isin()' takes at least 3 arguments ($lenarg given),";
348             }
349              
350 0           my $mode = pop;
351              
352 0 0 0       if ($mode ne "s" && $mode ne "l" && $mode ne "h") {
      0        
353 0           croak "Error: Last argument to 'isin()' must be 's', 'l' or 'h',";
354             }
355              
356 0 0         if ($mode eq "s") {
357              
358 0 0         if ($lenarg != 3) {
359 0           croak "Error: 'isin()' in mode 's' takes exactly 3 arguments ($lenarg given),";
360             }
361              
362 0 0         if ($_[0] =~ m/\Q$_[1]\E/) {
363 0           return 1;
364             }
365 0           return 0;
366             }
367              
368 0 0         if ($mode eq "l") {
369 0           my $a = pop;
370 0           for (@_) {
371 0 0         if ($_ eq $a) {
372 0           return 1;
373             }
374             }
375 0           return 0;
376             }
377              
378             # Only mode 'h' is left by now.
379              
380 0 0         if ($lenarg % 2) {
381 0           croak "Error: Unsuitable arguments to 'isin()' in 'h'-mode,";
382             }
383              
384 0           my $key = pop;
385 0           my %hash = @_;
386              
387 0 0         if (exists $hash{$key}) {
388 0           return 1;
389             }
390             else {
391 0           return 0;
392             }
393             }
394              
395             sub len {
396              
397 0     0 1   my $lenarg = @_;
398              
399 0 0         if ($lenarg < 2) {
400 0           croak "Error: 'len()' takes at least 2 arguments ($lenarg given),";
401             }
402              
403 0           my $mode = pop;
404              
405 0 0 0       if ($mode ne "s" && $mode ne "l" && $mode ne "h") {
      0        
406 0           croak "Error: Last argument to 'len()' must be 's', 'l' or 'h',";
407             }
408              
409 0 0         if ($mode eq "s") {
410              
411 0 0         if ($lenarg != 2) {
412 0           croak "Error: 'len()' in mode 's' takes exactly 2 arguments ($lenarg given),";
413             }
414              
415 0           return length($_[0]);
416             }
417              
418 0 0         if ($mode eq "l") {
419 0           return $lenarg - 1;
420             }
421              
422             # Only mode 'h' is left by now.
423              
424 0 0         if (! $lenarg % 2) {
425 0           croak "Error: Unsuitable arguments to 'isin()' in 'h'-mode,";
426             }
427              
428 0           return ($lenarg - 1) / 2;
429             }
430              
431              
432             # File-related-Functions
433              
434             sub isdir {
435              
436 0     0 1   checkArgs(1, @_);
437              
438 0 0         if(-d $_[0]) {
439 0           return 1;
440             }
441             else {
442 0           return 0;
443             }
444             }
445              
446             sub isfile {
447              
448 0     0 1   checkArgs(1, @_);
449              
450 0 0         if(-f $_[0]) {
451 0           return 1;
452             }
453             else {
454 0           return 0;
455             }
456             }
457              
458             sub readfile {
459              
460 0     0 1   checkArgs(1, @_);
461              
462 0           my $file = shift;
463              
464 0 0         open(FH, "<$file") or croak "Error reading file '$file',";
465 0           my @a = ; # Gulp !
466 0           close(FH);
467              
468 0           return @a;
469             }
470              
471              
472             sub writefile {
473              
474 0 0   0 1   if($#_ < 1) {
475 0           croak "Error: Function 'writefile()' needs a list to write to a file as an argument,";
476             }
477              
478 0           my ($file, @a) = @_;
479              
480 0 0         open(FH, ">$file") or croak "Error writing to file '$file',";
481              
482 0           print(FH @a);
483              
484 0           close(FH);
485             }
486              
487             sub listdir {
488              
489 0     0 1   checkArgs(1, @_);
490              
491 0           my $dir = shift;
492 0 0         if (! -d $dir) {
493 0           croak "Error: No such directory: '$dir',";
494             }
495 0           my $filename;
496 0           my @files = ();
497 0 0         opendir (DIR, $dir) || croak "Error opening directory '$dir',";
498 0           while(($filename = readdir(DIR))){
499 0 0 0       if ($filename ne "." && $filename ne "..") {
500 0           push(@files, "$filename");
501             }
502             }
503 0           return @files;
504             }
505              
506             sub oslistdir {
507 0     0 1   return listdir(@_);
508             }
509              
510              
511             # System-related-Functions
512              
513             sub osname {
514              
515 0     0 1   checkArgs(0);
516              
517 0           return $^O;
518             }
519              
520             1;
521              
522             __END__