File Coverage

blib/lib/Data/Munge.pm
Criterion Covered Total %
statement 69 69 100.0
branch 28 36 77.7
condition 9 9 100.0
subroutine 18 18 100.0
pod 10 10 100.0
total 134 142 94.3


line stmt bran cond sub pod time code
1             package Data::Munge;
2              
3 4     4   108494 use strict;
  4         11  
  4         134  
4 4     4   22 use warnings;
  4         7  
  4         136  
5 4     4   21 use base qw(Exporter);
  4         10  
  4         4901  
6              
7 9     9   542 sub _eval { eval $_[0] } # empty lexical scope
8              
9             our $VERSION = '0.096';
10             our @EXPORT = qw(
11             byval
12             elem
13             eval_string
14             list2re
15             mapval
16             rec
17             replace
18             slurp
19             submatches
20             trim
21             );
22              
23             sub byval (&$) {
24 1     1 1 841 my ($f, $x) = @_;
25 1         3 local *_ = \$x;
26 1         4 $f->($_);
27 1         9 $x
28             }
29              
30             sub elem {
31 37     37 1 778 my ($k, $xs) = @_;
32 37 100       90 if (ref $k) {
    100          
33 28         54 for my $x (@$xs) {
34 43 100 100     196 return 1 if ref $x && $k == $x;
35             }
36             } elsif (defined $k) {
37 8         14 for my $x (@$xs) {
38 15 100 100     97 return 1 if defined $x && !ref $x && $k eq $x;
      100        
39             }
40             } else {
41 1         4 for my $x (@$xs) {
42 1 50       9 return 1 if !defined $x;
43             }
44             }
45 18         72 !1
46             }
47              
48             sub eval_string {
49 9     9 1 1833 my ($code) = @_;
50 9         28 my ($package, $file, $line) = caller;
51 9         17 local $Data::Munge::_err = $@;
52 9         32 $code = qq{\$\@ = \$Data::Munge::_err; package $package; # eval_string()\n#line $line "$file"\n$code};
53 9 50       33 my @r = wantarray ? _eval $code : scalar _eval $code;
54 9 100       85 die $@ if $@;
55 6         35 $@ = $Data::Munge::_err;
56 6 50       30 wantarray ? @r : $r[0]
57             }
58              
59             sub list2re {
60 5 100   5 1 34 @_ or return qr/(?!)/;
61 4 50       23 my $re = join '|', map quotemeta, sort {length $b <=> length $a || $a cmp $b } @_;
  20         58  
62 4 100       17 $re eq '' and $re = '(?#)';
63 4         134 qr/$re/
64             }
65              
66             sub mapval (&@) {
67 1     1 1 2 my $f = shift;
68 1         3 my @xs = @_;
69 1         3 map { $f->($_); $_ } @xs
  3         7  
  3         20  
70             }
71              
72             if ($] >= 5.016) {
73 4     4   82 eval_string <<'EOT';
  4         14  
74             use v5.16;
75 1     1 1 3 sub rec (&) {
76 11     11   546 my ($f) = @_;
77 1         5 sub { $f->(__SUB__, @_) }
78             }
79             EOT
80             } elsif (eval { require Scalar::Util } && defined &Scalar::Util::weaken) {
81             *rec = sub (&) {
82             my ($f) = @_;
83             my $w;
84             my $r = $w = sub { $f->($w, @_) };
85             Scalar::Util::weaken($w);
86             $r
87             };
88             } else {
89             # slow but always works
90             *rec = sub (&) {
91             my ($f) = @_;
92             sub { $f->(&rec($f), @_) }
93             };
94             }
95              
96             sub replace {
97 7     7 1 35 my ($str, $re, $x, $g) = @_;
98             my $f = ref $x ? $x : sub {
99 28     28   28 my $r = $x;
100 28         35 $r =~ s{\$([\$&`'0-9]|\{([0-9]+)\})}{
101 2 50       39 $+ eq '$' ? '$' :
    50          
    50          
    50          
102             $+ eq '&' ? $_[0] :
103             $+ eq '`' ? substr($_[-1], 0, $_[-2]) :
104             $+ eq "'" ? substr($_[-1], $_[-2] + length $_[0]) :
105             $_[$+]
106             }eg;
107 28         88 $r
108 7 100       42 };
109 7 100       18 if ($g) {
110 6         46 $str =~ s{$re}{ $f->(substr($str, $-[0], $+[0] - $-[0]), submatches(), $-[0], $str) }eg;
  30         141  
111             } else {
112 1         9 $str =~ s{$re}{ $f->(substr($str, $-[0], $+[0] - $-[0]), submatches(), $-[0], $str) }e;
  1         6  
113             }
114 7         71 $str
115             }
116              
117             sub slurp {
118 1     1 1 369 local $/;
119 1         26 scalar readline $_[0]
120             }
121              
122             sub submatches {
123 4     4   27 no strict 'refs';
  4         6  
  4         611  
124 33     33 1 134 map $$_, 1 .. $#+
125             }
126              
127             sub trim {
128 9     9 1 16 my ($s) = @_;
129 9 100       28 return undef if !defined $s;
130 8         26 $s =~ s/^\s+//;
131 8         20 $s =~ s/\s+\z//;
132 8         35 $s
133             }
134              
135             'ok'
136              
137             __END__