File Coverage

blib/lib/Data/Unixish.pm
Criterion Covered Total %
statement 137 148 92.5
branch 52 66 78.7
condition n/a
subroutine 31 34 91.1
pod 21 21 100.0
total 241 269 89.5


line stmt bran cond sub pod time code
1             package Data::Unixish;
2              
3             our $DATE = '2019-01-06'; # DATE
4             our $VERSION = '1.570'; # VERSION
5              
6 42     42   2935 use 5.010001;
  42         157  
7 42     42   227 use strict;
  42         82  
  42         895  
8 42     42   230 use warnings;
  42         145  
  42         1123  
9              
10 42     42   17337 use Module::Load;
  42         54942  
  42         312  
11 42     42   18835 use Package::Util::Lite qw(package_exists);
  42         16904  
  42         28419  
12              
13             require Exporter;
14             our @ISA = qw(Exporter);
15             our @EXPORT_OK =
16             qw(
17             aduxa cduxa fduxa lduxa
18             aduxc cduxc fduxc lduxc
19             aduxf cduxf fduxf lduxf
20             aduxl cduxl fduxl lduxl
21              
22             siduxs
23             aiduxa aiduxl
24             liduxa liduxl
25             );
26             our %EXPORT_TAGS = (
27             all => [
28             qw/
29             aduxa cduxa fduxa lduxa
30             aduxc cduxc fduxc lduxc
31             aduxf cduxf fduxf lduxf
32             aduxl cduxl fduxl lduxl
33              
34             siduxs
35             aiduxa aiduxl
36             liduxa liduxl
37             /],
38             );
39              
40             sub _dux {
41 51     51   180 my $accepts = shift;
42 51         113 my $returns = shift;
43              
44 51         101 my $func = shift;
45              
46 51         91 my %args;
47              
48 51         94 my ($icallback, $ocallback);
49 51 100       227 if ($accepts eq 'c') {
50 6         29 $icallback = shift;
51             }
52 51 100       145 if ($returns eq 'c') {
53 4         13 $ocallback = shift;
54             }
55              
56 51 100       266 if ($accepts eq 'f') {
    100          
    100          
    50          
57 14         3211 require Tie::File;
58 14         80285 my @in;
59 14         144 tie @in, "Tie::File", @_;
60 14         4509 $args{in} = \@in;
61             } elsif ($accepts eq 'c') {
62 6         95 require Tie::Simple;
63 6         32 my @in;
64             my @els;
65 6         19 my $elcount = 0;
66             tie(@in, "Tie::Simple", undef,
67             FETCHSIZE => sub {
68 20     20   376 my $data = shift; # from Tie::Simple
69 20         78 my @res = $icallback->();
70 20         144 $elcount += @res;
71 20         65 push @els, @res;
72             #say "D: res=[".join(",", @res), "], elcount=$elcount";
73 20         149 $elcount;
74             },
75             FETCH => sub {
76 15     15   210 my $data = shift; # from Tie::Simple
77 15         78 shift @els;
78             }
79 6         326 );
80 6         111 $args{in} = \@in;
81             } elsif ($accepts eq 'l') {
82 15         45 $args{in} = \@_;
83             } elsif ($accepts eq 'a') {
84 16         63 $args{in} = $_[0];
85             } else {
86 0         0 die "Invalid accepts, must be a|c|f|l";
87             }
88              
89 51 100       180 if (ref($func) eq 'ARRAY') {
90 10         20 $args{$_} = $func->[1]{$_} for grep {/\A\w+\z/} keys %{$func->[1]};
  20         115  
  10         35  
91 10         30 $func = $func->[0];
92             }
93              
94 51         149 my $pkg = "Data::Unixish::$func";
95 51 100       260 load $pkg unless package_exists($pkg);
96 51         1147 my $funcleaf = $func; $funcleaf =~ s/.+:://;
  51         106  
97 51         236 my $funcname = "Data::Unixish::$func\::$funcleaf";
98 51 50       300 die "Subroutine &$funcname not defined" unless defined &$funcname;
99              
100 51         169 my @out;
101             my $kidfh;
102 51         0 my $pid;
103 51 100       218 if ($returns eq 'c') {
    100          
104 4         20 require Tie::Simple;
105             tie @out, "Tie::Simple", undef,
106             PUSH => sub {
107 13     13   203 my $data = shift; # from Tie::Simple
108 13         39 $ocallback->($_) for @_;
109 4         40 };
110 4         47 $args{out} = \@out;
111             } elsif ($returns eq 'f') {
112 14         2565 require Tie::Simple;
113             tie @out, "Tie::Simple", undef,
114             PUSH => sub {
115 13     13   441 my $data = shift; # from Tie::Simple
116 13         89 for my $item (@_) {
117 13 50       193 $item .= "\n" unless $item =~ /\n\z/;
118 13         385 print STDOUT $item;
119             }
120 14         37549 };
121 14         279 $args{out} = \@out;
122 14         17391 $pid = open $kidfh, "-|";
123 14 50       741 defined $pid or die "Can't fork: $!";
124             } else {
125 33         84 $args{out} = \@out;
126             }
127              
128 51 100       260 unless ($pid) {
129 42     42   300 no strict 'refs';
  42         80  
  42         29630  
130 41         600 my $res = $funcname->(%args);
131 41 50       266 die "Dux function $funcname failed: $res->[0] - $res->[1]"
132             unless $res->[0] == 200;
133             }
134              
135 51 100       488 if ($returns eq 'l') {
    100          
    100          
    50          
136 16 100       44 if (wantarray) {
137 11         82 return @out;
138             } else {
139 5         75 return $out[0];
140             }
141             } elsif ($returns eq 'a') {
142 17         144 return \@out;
143             } elsif ($returns eq 'c') {
144 4         27 return;
145             } elsif ($returns eq 'f') {
146 14 100       160 if ($pid) {
147 10         1163 return $kidfh;
148             } else {
149 4         261 exit;
150             }
151             } else {
152 0         0 die "Invalid returns, must be a|c|f|l";
153             }
154             }
155              
156 5     5 1 8300 sub aduxa { _dux('a', 'a', @_) }
157 2     2 1 839986 sub cduxa { _dux('c', 'a', @_) }
158 5     5 1 10945 sub fduxa { _dux('f', 'a', @_) }
159 5     5 1 22590 sub lduxa { _dux('l', 'a', @_) }
160              
161 1     1 1 3571 sub aduxc { _dux('a', 'c', @_) }
162 1     1 1 600 sub cduxc { _dux('c', 'c', @_) }
163 1     1 1 1263 sub fduxc { _dux('f', 'c', @_) }
164 1     1 1 727 sub lduxc { _dux('l', 'c', @_) }
165              
166 5     5 1 12040 sub aduxf { _dux('a', 'f', @_) }
167 2     2 1 8026 sub cduxf { _dux('c', 'f', @_) }
168 3     3 1 1963182 sub fduxf { _dux('f', 'f', @_) }
169 4     4 1 2761104 sub lduxf { _dux('l', 'f', @_) }
170              
171 5     5 1 25 sub aduxl { _dux('a', 'l', @_) }
172 1     1 1 388779 sub cduxl { _dux('c', 'l', @_) }
173 5     5 1 4690 sub fduxl { _dux('f', 'l', @_) }
174 5     5 1 10370 sub lduxl { _dux('l', 'l', @_) }
175              
176             sub _idux {
177 48     48   144 my $accepts = shift;
178 48         106 my $returns = shift;
179              
180 48         77 my $func = shift;
181              
182 48         104 my %args;
183             my @items;
184              
185 48 100       225 if ($accepts eq 's') {
    50          
    0          
186 4         7 @items = ($_[0]);
187             } elsif ($accepts eq 'a') {
188 44         73 @items = @{ $_[0] };
  44         151  
189             } elsif ($accepts eq 'l') {
190 0         0 @items = @_;
191             } else {
192 0         0 die "Invalid accepts, must be a|l|s";
193             }
194              
195 48 100       271 if (ref($func) eq 'ARRAY') {
196 44         93 $args{$_} = $func->[1]{$_} for keys %{$func->[1]};
  44         293  
197 44         254 $func = $func->[0];
198             }
199              
200 48         209 my $pkg = "Data::Unixish::$func";
201 48 100       222 load $pkg unless package_exists($pkg);
202 48         1008 my $funcleaf = $func; $funcleaf =~ s/.+:://;
  48         207  
203 48         151 my $funcname_i = "Data::Unixish::$func\::_${funcleaf}_item";
204 48 50       204 die "Subroutine &$funcname_i not defined" unless defined &$funcname_i;
205 48         144 my $funcname_b = "Data::Unixish::$func\::_${funcleaf}_begin";
206 48         140 my $funcname_e = "Data::Unixish::$func\::_${funcleaf}_end";
207              
208 48         80 my @res;
209             {
210 42     42   299 no strict 'refs';
  42         74  
  42         10776  
  48         76  
211 48 100       122 my @bres; @bres = $funcname_b->(\%args) if defined &$funcname_b;
  48         318  
212 48         164 for (@items) {
213 202         681 push @res, $funcname_i->($_, \%args);
214             }
215 48 100       384 $funcname_e->(\%args, @bres) if defined &$funcname_e;
216             }
217              
218 48 100       266 if ($returns eq 's') {
    50          
    50          
219 4         23 return $res[0];
220             } elsif ($returns eq 'l') {
221 0 0       0 if (wantarray) {
222 0         0 return @res;
223             } else {
224 0         0 return $res[0];
225             }
226             } elsif ($returns eq 'a') {
227 44         233 return \@res;
228             } else {
229 0         0 die "Invalid returns, must be a|l|s";
230             }
231             }
232              
233 4     4 1 7 sub siduxs { _idux('s', 's', @_) }
234              
235 44     44 1 300 sub aiduxa { _idux('a', 'a', @_) }
236 0     0 1   sub aiduxl { _idux('a', 'l', @_) }
237              
238 0     0 1   sub liduxa { _idux('l', 'a', @_) }
239 0     0 1   sub liduxl { _idux('l', 'l', @_) }
240              
241             1;
242             # ABSTRACT: Implementation for Unixish, a data transformation framework
243              
244             __END__