File Coverage

blib/lib/Data/Munge.pm
Criterion Covered Total %
statement 71 71 100.0
branch 30 38 78.9
condition 12 12 100.0
subroutine 18 18 100.0
pod 11 11 100.0
total 142 150 94.6


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