File Coverage

blib/lib/Switch.pm
Criterion Covered Total %
statement 207 290 71.3
branch 121 184 65.7
condition 79 122 64.7
subroutine 32 43 74.4
pod 0 13 0.0
total 439 652 67.3


line stmt bran cond sub pod time code
1             package Switch;
2              
3 3     3   8170 use 5.005;
  3         11  
  3         133  
4 3     3   16 use strict;
  3         6  
  3         112  
5 3     3   15 use vars qw($VERSION);
  3         9  
  3         195  
6 3     3   16 use Carp;
  3         11  
  3         233  
7              
8 3     3   3042 use if $] >= 5.011, 'deprecate';
  3         27  
  3         16  
9              
10             $VERSION = '2.17';
11            
12              
13             # LOAD FILTERING MODULE...
14 3     3   7362 use Filter::Util::Call;
  3         3411  
  3         671  
15              
16             sub __();
17              
18             # CATCH ATTEMPTS TO CALL case OUTSIDE THE SCOPE OF ANY switch
19              
20             $::_S_W_I_T_C_H = sub { croak "case/when statement not in switch/given block" };
21              
22             my $offset;
23             my $fallthrough;
24             my ($Perl5, $Perl6) = (0,0);
25              
26             sub import
27             {
28 3     3   71 $fallthrough = grep /\bfallthrough\b/, @_;
29 3         14 $offset = (caller)[2]+1;
30 3 50 66     43 filter_add({}) unless @_>1 && $_[1] eq 'noimport';
31 3         70 my $pkg = caller;
32 3     3   22 no strict 'refs';
  3         7  
  3         1147  
33 3         9 for ( qw( on_defined on_exists ) )
34             {
35 6         14 *{"${pkg}::$_"} = \&$_;
  6         39  
36             }
37 3 100       28 *{"${pkg}::__"} = \&__ if grep /__/, @_;
  2         10  
38 3 100       25 $Perl6 = 1 if grep(/Perl\s*6/i, @_);
39 3 100 66     36 $Perl5 = 1 if grep(/Perl\s*5/i, @_) || !grep(/Perl\s*6/i, @_);
40 3         32 1;
41             }
42              
43             sub unimport
44             {
45 0     0   0 filter_del()
46             }
47              
48             sub filter
49             {
50 5     5 0 17 my($self) = @_ ;
51 5         26 local $Switch::file = (caller)[1];
52              
53 5         13 my $status = 1;
54 5         192 $status = filter_read(1_000_000);
55 5 50       26 return $status if $status<0;
56 5         20 $_ = filter_blocks($_,$offset);
57 5 100       86 $_ = "# line $offset\n" . $_ if $offset; undef $offset;
  5         74  
58 5         20269 return $status;
59             }
60              
61 3     3   3960 use Text::Balanced ':ALL';
  3         100031  
  3         22972  
62              
63             sub line
64             {
65 461     461 0 1758 my ($pretext,$offset) = @_;
66 461   50     2728 ($pretext=~tr/\n/\n/)+($offset||0);
67             }
68              
69             sub is_block
70             {
71 26     26 0 394 local $SIG{__WARN__}=sub{die$@};
  34     34   337  
72 34         139 local $^W=1;
73 34         3182 my $ishash = defined eval 'my $hr='.$_[0];
74 34         156 undef $@;
75 34         273 return !$ishash;
76             }
77              
78             my $pod_or_DATA = qr/ ^=[A-Za-z] .*? ^=cut (?![A-Za-z]) .*? $
79             | ^__(DATA|END)__\n.*
80             /smx;
81              
82             my $casecounter = 1;
83             sub filter_blocks
84             {
85 466     466 0 1820 my ($source, $line) = @_;
86 466 100 100     4791 return $source unless $Perl5 && $source =~ /case|switch/
      100        
      66        
87             || $Perl6 && $source =~ /when|given|default/;
88 26         95 pos $source = 0;
89 26         63 my $text = "";
90 26         1243 component: while (pos $source < length $source)
91             {
92 2553 50       9838 if ($source =~ m/(\G\s*use\s+Switch\b)/gc)
93             {
94 0         0 $text .= q{use Switch 'noimport'};
95 0         0 next component;
96             }
97 2553         12448 my @pos = Text::Balanced::_match_quotelike(\$source,qr/\s*/,1,0);
98 2553 100       83326 if (defined $pos[0])
99             {
100 58         120 my $pre = substr($source,$pos[0],$pos[1]); # matched prefix
101 58         71 my $iEol;
102 58 50 66     318 if( substr($source,$pos[4],$pos[5]) eq '/' && # 1st delimiter
      66        
      33        
      33        
103             substr($source,$pos[2],$pos[3]) eq '' && # no op like 'm'
104             index( substr($source,$pos[16],$pos[17]), 'x' ) == -1 && # no //x
105             ($iEol = index( $source, "\n", $pos[4] )) > 0 &&
106             $iEol < $pos[8] ){ # embedded newlines
107             # If this is a pattern, it isn't compatible with Switch. Backup past 1st '/'.
108 0         0 pos( $source ) = $pos[6];
109 0         0 $text .= $pre . substr($source,$pos[2],$pos[6]-$pos[2]);
110             } else {
111 58         138 $text .= $pre . substr($source,$pos[2],$pos[18]-$pos[2]);
112             }
113 58         222 next component;
114             }
115 2495 100       13216 if ($source =~ m/(\G\s*$pod_or_DATA)/gc) {
116 2         6 $text .= $1;
117 2         23 next component;
118             }
119 2493         11343 @pos = Text::Balanced::_match_variable(\$source,qr/\s*/);
120 2493 100       91213 if (defined $pos[0])
121             {
122 162 100       457 $text .= " " if $pos[0] < $pos[2];
123 162         347 $text .= substr($source,$pos[0],$pos[4]-$pos[0]);
124 162         604 next component;
125             }
126              
127 2331 100 100     52436 if ($Perl5 && $source =~ m/\G(\n*)(\s*)(switch)\b(?=\s*[(])/gc
    100 100        
      66        
      100        
      66        
      100        
      100        
      66        
      66        
      66        
128             || $Perl6 && $source =~ m/\G(\n*)(\s*)(given)\b(?=\s*[(])/gc
129             || $Perl6 && $source =~ m/\G(\n*)(\s*)(given)\b(.*)(?=\{)/gc)
130             {
131 20         64 my $keyword = $3;
132 20         65 my $arg = $4;
133 20         71 $text .= $1.$2.'S_W_I_T_C_H: while (1) ';
134 20 100       56 unless ($arg) {
135             @pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/\(/,qr/\)/,qr/[[{(<]/,qr/[]})>]/,undef)
136 19 50       208 or do {
137 0         0 die "Bad $keyword statement (problem in the parentheses?) near $Switch::file line ", line(substr($source,0,pos $source),$line), "\n";
138             };
139 19         6651 $arg = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
140             }
141 20 50 33     359 $arg =~ s {^\s*[(]\s*%} { ( \\\%} ||
      33        
142             $arg =~ s {^\s*[(]\s*m\b} { ( qr} ||
143             $arg =~ s {^\s*[(]\s*/} { ( qr/} ||
144             $arg =~ s {^\s*[(]\s*qw} { ( \\qw};
145             @pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/\{/,qr/\}/,qr/\{/,qr/\}/,undef)
146 20 50       204 or do {
147 0         0 die "Bad $keyword statement (problem in the code block?) near $Switch::file line ", line(substr($source,0, pos $source), $line), "\n";
148             };
149 20         369104 my $code = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
150 20         238 $code =~ s/{/{ local \$::_S_W_I_T_C_H; Switch::switch($arg);/;
151 20         332 $text .= $code . 'continue {last}';
152 20         105 next component;
153             }
154             elsif ($Perl5 && $source =~ m/\G(\s*)(case\b)(?!\s*=>)/gc
155             || $Perl6 && $source =~ m/\G(\s*)(when\b)(?!\s*=>)/gc
156             || $Perl6 && $source =~ m/\G(\s*)(default\b)(?=\s*\{)/gc)
157             {
158 212         488 my $keyword = $2;
159 212 50       686 $text .= $1 . ($keyword eq "default"
160             ? "if (1)"
161             : "if (Switch::case");
162              
163 212 50 66     2118 if ($keyword eq "default") {
    100 66        
    100 33        
    50 66        
    100          
    50          
164             # Nothing to do
165             }
166             elsif (@pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/\{/,qr/\}/,qr/\{/,qr/\}/,undef)) {
167 34         11110 my $code = substr($source,$pos[0],$pos[4]-$pos[0]);
168 34 50       101 $text .= " " if $pos[0] < $pos[2];
169 34 100       95 $text .= "sub " if is_block $code;
170 34         136 $text .= filter_blocks($code,line(substr($source,0,$pos[0]),$line)) . ")";
171             }
172 11         917 elsif (@pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/[[(]/,qr/[])]/,qr/[[({]/,qr/[])}]/,undef)) {
173 155         87900 my $code = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
174 155 50 33     2165 $code =~ s {^\s*[(]\s*%} { ( \\\%} ||
      33        
175             $code =~ s {^\s*[(]\s*m\b} { ( qr} ||
176             $code =~ s {^\s*[(]\s*/} { ( qr/} ||
177             $code =~ s {^\s*[(]\s*qw} { ( \\qw};
178 155 50       453 $text .= " " if $pos[0] < $pos[2];
179 155         315 $text .= "$code)";
180             }
181             elsif ($Perl6 && do{@pos = Text::Balanced::_match_variable(\$source,qr/\s*/)}) {
182 0         0 my $code = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
183 0 0       0 $code =~ s {^\s*%} { \%} ||
184             $code =~ s {^\s*@} { \@};
185 0 0       0 $text .= " " if $pos[0] < $pos[2];
186 0         0 $text .= "$code)";
187             }
188             elsif ( @pos = Text::Balanced::_match_quotelike(\$source,qr/\s*/,1,0)) {
189 4         467 my $code = substr($source,$pos[2],$pos[18]-$pos[2]);
190 4         16 $code = filter_blocks($code,line(substr($source,0,$pos[2]),$line));
191 4 50 33     55 $code =~ s {^\s*m} { qr} ||
192             $code =~ s {^\s*/} { qr/} ||
193             $code =~ s {^\s*qw} { \\qw};
194 4 50       25 $text .= " " if $pos[0] < $pos[2];
195 4         11 $text .= "$code)";
196             }
197             elsif ($Perl5 && $source =~ m/\G\s*(([^\$\@{])[^\$\@{]*)(?=\s*{)/gc
198             || $Perl6 && $source =~ m/\G\s*([^;{]*)()/gc) {
199 19         1778 my $code = filter_blocks($1,line(substr($source,0,pos $source),$line));
200 19 50       71 $text .= ' \\' if $2 eq '%';
201 19         52 $text .= " $code)";
202             }
203             else {
204 0         0 die "Bad $keyword statement (invalid $keyword value?) near $Switch::file line ", line(substr($source,0,pos $source), $line), "\n";
205             }
206              
207 212 50 66     21382 die "Missing opening brace or semi-colon after 'when' value near $Switch::file line ", line(substr($source,0,pos $source), $line), "\n"
208             unless !$Perl6 || $source =~ m/\G(\s*)(?=;|\{)/gc;
209              
210 212         2006 do{@pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/\{/,qr/\}/,qr/\{/,qr/\}/,undef)}
211 212 100       256 or do {
212 2 50       84 if ($source =~ m/\G\s*(?=([};]|\Z))/gc) {
213 2         5 $casecounter++;
214 2         14 next component;
215             }
216 0         0 die "Bad $keyword statement (problem in the code block?) near $Switch::file line ", line(substr($source,0,pos $source),$line), "\n";
217             };
218 210         146369 my $code = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
219 210 100       883 $code =~ s/}(?=\s*\Z)/;last S_W_I_T_C_H }/
220             unless $fallthrough;
221 210         692 $text .= "{ while (1) $code continue { goto C_A_S_E_$casecounter } last S_W_I_T_C_H; C_A_S_E_$casecounter: }";
222 210         276 $casecounter++;
223 210         905 next component;
224             }
225              
226 2099         6478 $source =~ m/\G(\s*(-[sm]\s+|\w+|#.*\n|\W))/gc;
227 2099         11650 $text .= $1;
228             }
229 26         296 $text;
230             }
231              
232              
233              
234             sub in
235             {
236 135     135 0 195 my ($x,$y) = @_;
237 135         144 my @numy;
238 135         223 for my $nextx ( @$x )
239             {
240 153   33     855 my $numx = ref($nextx) || defined $nextx && (~$nextx&$nextx) eq 0;
241 153         335 for my $j ( 0..$#$y )
242             {
243 958         1222 my $nexty = $y->[$j];
244 958 100 33     4118 push @numy, ref($nexty) || defined $nexty && (~$nexty&$nexty) eq 0
245             if @numy <= $j;
246 958 100 100     7079 return 1 if $numx && $numy[$j] && $nextx==$nexty
      100        
      100        
247             || $nextx eq $nexty;
248            
249             }
250             }
251 94         473 return "";
252             }
253              
254             sub on_exists
255             {
256 0 0 0 0 0 0 my $ref = @_==1 && ref($_[0]) eq 'HASH' ? $_[0] : { @_ };
257 0         0 [ keys %$ref ]
258             }
259              
260             sub on_defined
261             {
262 0 0 0 0 0 0 my $ref = @_==1 && ref($_[0]) eq 'HASH' ? $_[0] : { @_ };
263 0         0 [ grep { defined $ref->{$_} } keys %$ref ]
  0         0  
264             }
265              
266             sub switch(;$)
267             {
268 53 50   53 0 1059 my ($s_val) = @_ ? $_[0] : $_;
269 53         93 my $s_ref = ref $s_val;
270            
271 53 100 66     401 if ($s_ref eq 'CODE')
    100 100        
    100          
    100          
    50          
    100          
    50          
272             {
273             $::_S_W_I_T_C_H =
274 114     114   157 sub { my $c_val = $_[0];
275 114 100       362 return $s_val == $c_val if ref $c_val eq 'CODE';
276 84 100       210 return $s_val->(@$c_val) if ref $c_val eq 'ARRAY';
277 54         113 return $s_val->($c_val);
278 6         26 };
279             }
280             elsif ($s_ref eq "" && defined $s_val && (~$s_val&$s_val) eq 0) # NUMERIC SCALAR
281             {
282             $::_S_W_I_T_C_H =
283 170     170   219 sub { my $c_val = $_[0];
284 170         245 my $c_ref = ref $c_val;
285 170 100 66     945 return $s_val == $c_val if $c_ref eq ""
      100        
286             && defined $c_val
287             && (~$c_val&$c_val) eq 0;
288 125 100       321 return $s_val eq $c_val if $c_ref eq "";
289 101 100       294 return in([$s_val],$c_val) if $c_ref eq 'ARRAY';
290 57 100       165 return $c_val->($s_val) if $c_ref eq 'CODE';
291 33 100       81 return $c_val->call($s_val) if $c_ref eq 'Switch';
292 24 50       51 return scalar $s_val=~/$c_val/
293             if $c_ref eq 'Regexp';
294 24 50       117 return scalar $c_val->{$s_val}
295             if $c_ref eq 'HASH';
296 0         0 return;
297 18         84 };
298             }
299             elsif ($s_ref eq "") # STRING SCALAR
300             {
301             $::_S_W_I_T_C_H =
302 136     136   171 sub { my $c_val = $_[0];
303 136         171 my $c_ref = ref $c_val;
304 136 100       471 return $s_val eq $c_val if $c_ref eq "";
305 72 100       175 return in([$s_val],$c_val) if $c_ref eq 'ARRAY';
306 48 100       133 return $c_val->($s_val) if $c_ref eq 'CODE';
307 16 50       32 return $c_val->call($s_val) if $c_ref eq 'Switch';
308 16 50       41 return scalar $s_val=~/$c_val/
309             if $c_ref eq 'Regexp';
310 16 50       80 return scalar $c_val->{$s_val}
311             if $c_ref eq 'HASH';
312 0         0 return;
313 8         34 };
314             }
315             elsif ($s_ref eq 'ARRAY')
316             {
317             $::_S_W_I_T_C_H =
318 113     113   287 sub { my $c_val = $_[0];
319 113         172 my $c_ref = ref $c_val;
320 113 100       312 return in($s_val,[$c_val]) if $c_ref eq "";
321 76 100       165 return in($s_val,$c_val) if $c_ref eq 'ARRAY';
322 46 100       140 return $c_val->(@$s_val) if $c_ref eq 'CODE';
323 22 50       47 return $c_val->call(@$s_val)
324             if $c_ref eq 'Switch';
325 22 100       84 return scalar grep {$_=~/$c_val/} @$s_val
  22         145  
326             if $c_ref eq 'Regexp';
327 12 50       51 return scalar grep {$c_val->{$_}} @$s_val
  16         56  
328             if $c_ref eq 'HASH';
329 0         0 return;
330 16         83 };
331             }
332             elsif ($s_ref eq 'Regexp')
333             {
334             $::_S_W_I_T_C_H =
335 0     0   0 sub { my $c_val = $_[0];
336 0         0 my $c_ref = ref $c_val;
337 0 0       0 return $c_val=~/s_val/ if $c_ref eq "";
338 0 0       0 return scalar grep {$_=~/s_val/} @$c_val
  0         0  
339             if $c_ref eq 'ARRAY';
340 0 0       0 return $c_val->($s_val) if $c_ref eq 'CODE';
341 0 0       0 return $c_val->call($s_val) if $c_ref eq 'Switch';
342 0 0       0 return $s_val eq $c_val if $c_ref eq 'Regexp';
343 0 0       0 return grep {$_=~/$s_val/ && $c_val->{$_}} keys %$c_val
  0 0       0  
344             if $c_ref eq 'HASH';
345 0         0 return;
346 0         0 };
347             }
348             elsif ($s_ref eq 'HASH')
349             {
350             $::_S_W_I_T_C_H =
351 68     68   101 sub { my $c_val = $_[0];
352 68         108 my $c_ref = ref $c_val;
353 68 100       229 return $s_val->{$c_val} if $c_ref eq "";
354 48 100       120 return scalar grep {$s_val->{$_}} @$c_val
  400         686  
355             if $c_ref eq 'ARRAY';
356 28 100       92 return $c_val->($s_val) if $c_ref eq 'CODE';
357 12 50       25 return $c_val->call($s_val) if $c_ref eq 'Switch';
358 12 0       26 return grep {$_=~/$c_val/ && $s_val->{"$_"}} keys %$s_val
  0 50       0  
359             if $c_ref eq 'Regexp';
360 12 50       99 return $s_val==$c_val if $c_ref eq 'HASH';
361 0         0 return;
362 4         20 };
363             }
364             elsif ($s_ref eq 'Switch')
365             {
366             $::_S_W_I_T_C_H =
367 3     3   5 sub { my $c_val = $_[0];
368 3 50       10 return $s_val == $c_val if ref $c_val eq 'Switch';
369 3 50       8 return $s_val->call(@$c_val)
370             if ref $c_val eq 'ARRAY';
371 3         11 return $s_val->call($c_val);
372 1         6 };
373             }
374             else
375             {
376 0         0 croak "Cannot switch on $s_ref";
377             }
378 53         133 return 1;
379             }
380              
381 606     606 0 7696 sub case($) { local $SIG{__WARN__} = \&carp;
382 606         1275 $::_S_W_I_T_C_H->(@_); }
383              
384             # IMPLEMENT __
385              
386             my $placeholder = bless { arity=>1, impl=>sub{$_[1+$_[0]]} };
387              
388 12     12   256 sub __() { $placeholder }
389              
390             sub __arg($)
391             {
392 0     0   0 my $index = $_[0]+1;
393 0     0   0 bless { arity=>0, impl=>sub{$_[$index]} };
  0         0  
394             }
395              
396             sub hosub(&@)
397 0     0 0 0 {
398             # WRITE THIS
399             }
400              
401             sub call
402             {
403 12     12 0 25 my ($self,@args) = @_;
404 12         78 return $self->{impl}->(0,@args);
405             }
406              
407             sub meta_bop(&)
408             {
409 84     84 0 131 my ($op) = @_;
410             sub
411             {
412 3     3   19 my ($left, $right, $reversed) = @_;
413 3 50       28 ($right,$left) = @_ if $reversed;
414              
415 3     3   9 my $rop = ref $right eq 'Switch'
416             ? $right
417 3 50       35 : bless { arity=>0, impl=>sub{$right} };
418              
419 0     0   0 my $lop = ref $left eq 'Switch'
420             ? $left
421 3 50       28 : bless { arity=>0, impl=>sub{$left} };
422              
423 3         11 my $arity = $lop->{arity} + $rop->{arity};
424              
425             return bless {
426             arity => $arity,
427 3     3   5 impl => sub { my $start = shift;
428 3         9 return $op->($lop->{impl}->($start,@_),
429             $rop->{impl}->($start+$lop->{arity},@_));
430             }
431 3         26 };
432 84         727 };
433             }
434              
435             sub meta_uop(&)
436             {
437 27     27 0 36 my ($op) = @_;
438             sub
439             {
440 0     0     my ($left) = @_;
441              
442 0     0     my $lop = ref $left eq 'Switch'
443             ? $left
444 0 0         : bless { arity=>0, impl=>sub{$left} };
445              
446 0           my $arity = $lop->{arity};
447              
448             return bless {
449             arity => $arity,
450 0     0     impl => sub { $op->($lop->{impl}->(@_)) }
451 0           };
452 27         221 };
453             }
454              
455              
456             use overload
457 0         0 "+" => meta_bop {$_[0] + $_[1]},
458 0         0 "-" => meta_bop {$_[0] - $_[1]},
459 0         0 "*" => meta_bop {$_[0] * $_[1]},
460 0         0 "/" => meta_bop {$_[0] / $_[1]},
461 0         0 "%" => meta_bop {$_[0] % $_[1]},
462 0         0 "**" => meta_bop {$_[0] ** $_[1]},
463 0         0 "<<" => meta_bop {$_[0] << $_[1]},
464 0         0 ">>" => meta_bop {$_[0] >> $_[1]},
465 0         0 "x" => meta_bop {$_[0] x $_[1]},
466 0         0 "." => meta_bop {$_[0] . $_[1]},
467 0         0 "<" => meta_bop {$_[0] < $_[1]},
468 0         0 "<=" => meta_bop {$_[0] <= $_[1]},
469 3         18 ">" => meta_bop {$_[0] > $_[1]},
470 0         0 ">=" => meta_bop {$_[0] >= $_[1]},
471 0         0 "==" => meta_bop {$_[0] == $_[1]},
472 0         0 "!=" => meta_bop {$_[0] != $_[1]},
473 0         0 "<=>" => meta_bop {$_[0] <=> $_[1]},
474 0         0 "lt" => meta_bop {$_[0] lt $_[1]},
475 0         0 "le" => meta_bop {$_[0] le $_[1]},
476 0         0 "gt" => meta_bop {$_[0] gt $_[1]},
477 0         0 "ge" => meta_bop {$_[0] ge $_[1]},
478 0         0 "eq" => meta_bop {$_[0] eq $_[1]},
479 0         0 "ne" => meta_bop {$_[0] ne $_[1]},
480 0         0 "cmp" => meta_bop {$_[0] cmp $_[1]},
481 0         0 "\&" => meta_bop {$_[0] & $_[1]},
482 0         0 "^" => meta_bop {$_[0] ^ $_[1]},
483 0         0 "|" => meta_bop {$_[0] | $_[1]},
484 0         0 "atan2" => meta_bop {atan2 $_[0], $_[1]},
485              
486 0         0 "neg" => meta_uop {-$_[0]},
487 0         0 "!" => meta_uop {!$_[0]},
488 0         0 "~" => meta_uop {~$_[0]},
489 0         0 "cos" => meta_uop {cos $_[0]},
490 0         0 "sin" => meta_uop {sin $_[0]},
491 0         0 "exp" => meta_uop {exp $_[0]},
492 0         0 "abs" => meta_uop {abs $_[0]},
493 0         0 "log" => meta_uop {log $_[0]},
494 0         0 "sqrt" => meta_uop {sqrt $_[0]},
495 2     2   251 "bool" => sub { croak "Can't use && or || in expression containing __" },
496              
497             # "&()" => sub { $_[0]->{impl} },
498              
499             # "||" => meta_bop {$_[0] || $_[1]},
500             # "&&" => meta_bop {$_[0] && $_[1]},
501             # fallback => 1,
502 3     3   43 ;
  3         6  
  3         32  
503             1;
504              
505             __END__