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-10-26'; # DATE
4             our $VERSION = '1.571'; # VERSION
5              
6 46     46   3938 use 5.010001;
  46         185  
7 46     46   280 use strict;
  46         116  
  46         1055  
8 46     46   269 use warnings;
  46         142  
  46         1396  
9              
10 46     46   23213 use Module::Load;
  46         51541  
  46         275  
11 46     46   23991 use Package::Util::Lite qw(package_exists);
  46         21687  
  46         34604  
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   217 my $accepts = shift;
42 51         110 my $returns = shift;
43              
44 51         91 my $func = shift;
45              
46 51         98 my %args;
47              
48 51         80 my ($icallback, $ocallback);
49 51 100       224 if ($accepts eq 'c') {
50 6         36 $icallback = shift;
51             }
52 51 100       133 if ($returns eq 'c') {
53 4         12 $ocallback = shift;
54             }
55              
56 51 100       268 if ($accepts eq 'f') {
    100          
    100          
    50          
57 14         4083 require Tie::File;
58 14         96439 my @in;
59 14         189 tie @in, "Tie::File", @_;
60 14         3113 $args{in} = \@in;
61             } elsif ($accepts eq 'c') {
62 6         84 require Tie::Simple;
63 6         32 my @in;
64             my @els;
65 6         29 my $elcount = 0;
66             tie(@in, "Tie::Simple", undef,
67             FETCHSIZE => sub {
68 20     20   402 my $data = shift; # from Tie::Simple
69 20         91 my @res = $icallback->();
70 20         179 $elcount += @res;
71 20         106 push @els, @res;
72             #say "D: res=[".join(",", @res), "], elcount=$elcount";
73 20         184 $elcount;
74             },
75             FETCH => sub {
76 15     15   240 my $data = shift; # from Tie::Simple
77 15         82 shift @els;
78             }
79 6         143 );
80 6         139 $args{in} = \@in;
81             } elsif ($accepts eq 'l') {
82 15         48 $args{in} = \@_;
83             } elsif ($accepts eq 'a') {
84 16         58 $args{in} = $_[0];
85             } else {
86 0         0 die "Invalid accepts, must be a|c|f|l";
87             }
88              
89 51 100       204 if (ref($func) eq 'ARRAY') {
90 10         20 $args{$_} = $func->[1]{$_} for grep {/\A\w+\z/} keys %{$func->[1]};
  20         120  
  10         40  
91 10         25 $func = $func->[0];
92             }
93              
94 51         148 my $pkg = "Data::Unixish::$func";
95 51 100       297 load $pkg unless package_exists($pkg);
96 51         1400 my $funcleaf = $func; $funcleaf =~ s/.+:://;
  51         146  
97 51         172 my $funcname = "Data::Unixish::$func\::$funcleaf";
98 51 50       310 die "Subroutine &$funcname not defined" unless defined &$funcname;
99              
100 51         171 my @out;
101             my $kidfh;
102 51         0 my $pid;
103 51 100       241 if ($returns eq 'c') {
    100          
104 4         20 require Tie::Simple;
105             tie @out, "Tie::Simple", undef,
106             PUSH => sub {
107 13     13   245 my $data = shift; # from Tie::Simple
108 13         50 $ocallback->($_) for @_;
109 4         49 };
110 4         51 $args{out} = \@out;
111             } elsif ($returns eq 'f') {
112 14         2640 require Tie::Simple;
113             tie @out, "Tie::Simple", undef,
114             PUSH => sub {
115 13     13   576 my $data = shift; # from Tie::Simple
116 13         100 for my $item (@_) {
117 13 50       254 $item .= "\n" unless $item =~ /\n\z/;
118 13         548 print STDOUT $item;
119             }
120 14         47169 };
121 14         265 $args{out} = \@out;
122 14         14827 $pid = open $kidfh, "-|";
123 14 50       1068 defined $pid or die "Can't fork: $!";
124             } else {
125 33         75 $args{out} = \@out;
126             }
127              
128 51 100       285 unless ($pid) {
129 46     46   361 no strict 'refs';
  46         94  
  46         37597  
130 41         759 my $res = $funcname->(%args);
131 41 50       225 die "Dux function $funcname failed: $res->[0] - $res->[1]"
132             unless $res->[0] == 200;
133             }
134              
135 51 100       820 if ($returns eq 'l') {
    100          
    100          
    50          
136 16 100       48 if (wantarray) {
137 11         80 return @out;
138             } else {
139 5         90 return $out[0];
140             }
141             } elsif ($returns eq 'a') {
142 17         144 return \@out;
143             } elsif ($returns eq 'c') {
144 4         33 return;
145             } elsif ($returns eq 'f') {
146 14 100       155 if ($pid) {
147 10         1485 return $kidfh;
148             } else {
149 4         292 exit;
150             }
151             } else {
152 0         0 die "Invalid returns, must be a|c|f|l";
153             }
154             }
155              
156 5     5 1 8845 sub aduxa { _dux('a', 'a', @_) }
157 2     2 1 891034 sub cduxa { _dux('c', 'a', @_) }
158 5     5 1 12580 sub fduxa { _dux('f', 'a', @_) }
159 5     5 1 26695 sub lduxa { _dux('l', 'a', @_) }
160              
161 1     1 1 3164 sub aduxc { _dux('a', 'c', @_) }
162 1     1 1 691 sub cduxc { _dux('c', 'c', @_) }
163 1     1 1 1541 sub fduxc { _dux('f', 'c', @_) }
164 1     1 1 725 sub lduxc { _dux('l', 'c', @_) }
165              
166 5     5 1 14140 sub aduxf { _dux('a', 'f', @_) }
167 2     2 1 3938 sub cduxf { _dux('c', 'f', @_) }
168 3     3 1 1309464 sub fduxf { _dux('f', 'f', @_) }
169 4     4 1 1724716 sub lduxf { _dux('l', 'f', @_) }
170              
171 5     5 1 30 sub aduxl { _dux('a', 'l', @_) }
172 1     1 1 436836 sub cduxl { _dux('c', 'l', @_) }
173 5     5 1 3980 sub fduxl { _dux('f', 'l', @_) }
174 5     5 1 12790 sub lduxl { _dux('l', 'l', @_) }
175              
176             sub _idux {
177 55     55   131 my $accepts = shift;
178 55         125 my $returns = shift;
179              
180 55         102 my $func = shift;
181              
182 55         133 my %args;
183             my @items;
184              
185 55 100       262 if ($accepts eq 's') {
    50          
    0          
186 4         25 @items = ($_[0]);
187             } elsif ($accepts eq 'a') {
188 51         98 @items = @{ $_[0] };
  51         192  
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 55 100       316 if (ref($func) eq 'ARRAY') {
196 51         112 $args{$_} = $func->[1]{$_} for keys %{$func->[1]};
  51         352  
197 51         269 $func = $func->[0];
198             }
199              
200 55         243 my $pkg = "Data::Unixish::$func";
201 55 100       283 load $pkg unless package_exists($pkg);
202 55         1240 my $funcleaf = $func; $funcleaf =~ s/.+:://;
  55         250  
203 55         180 my $funcname_i = "Data::Unixish::$func\::_${funcleaf}_item";
204 55 50       260 die "Subroutine &$funcname_i not defined" unless defined &$funcname_i;
205 55         187 my $funcname_b = "Data::Unixish::$func\::_${funcleaf}_begin";
206 55         151 my $funcname_e = "Data::Unixish::$func\::_${funcleaf}_end";
207              
208 55         112 my @res;
209             {
210 46     46   366 no strict 'refs';
  46         89  
  46         13084  
  55         95  
211 55 100       98 my @bres; @bres = $funcname_b->(\%args) if defined &$funcname_b;
  55         371  
212 55         172 for (@items) {
213 225         723 push @res, $funcname_i->($_, \%args);
214             }
215 55 100       439 $funcname_e->(\%args, @bres) if defined &$funcname_e;
216             }
217              
218 55 100       305 if ($returns eq 's') {
    50          
    50          
219 4         30 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 51         319 return \@res;
228             } else {
229 0         0 die "Invalid returns, must be a|l|s";
230             }
231             }
232              
233 4     4 1 11 sub siduxs { _idux('s', 's', @_) }
234              
235 51     51 1 237 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__