File Coverage

blib/lib/Sub/Infix.pm
Criterion Covered Total %
statement 45 49 91.8
branch 20 24 83.3
condition 11 15 73.3
subroutine 16 19 84.2
pod 1 1 100.0
total 93 108 86.1


line stmt bran cond sub pod time code
1 1     1   142335 use 5.006;
  1         6  
  1         86  
2 1     1   6 use strict;
  1         3  
  1         39  
3 1     1   6 use warnings;
  1         31  
  1         90  
4              
5             package Sub::Infix;
6              
7             BEGIN {
8 1     1   3 $Sub::Infix::AUTHORITY = 'cpan:TOBYINK';
9 1         31 $Sub::Infix::VERSION = '0.004';
10             }
11              
12 1     1   6 use Exporter ();
  1         2  
  1         315  
13             our @ISA = qw( Exporter );
14             our @EXPORT = qw( infix );
15              
16             sub infix (&)
17             {
18 2     2 1 136 my $code = shift;
19 2     10   2778 sub () { bless +{ code => $code }, "Sub::Infix::PartialApplication" };
  10         3730  
20             }
21              
22             {
23             package Sub::Infix::PartialApplication;
24            
25 1     1   7 use Carp qw(croak);
  1         2  
  1         116  
26            
27             BEGIN {
28 1 50   1   2 eval { require Scalar::Util; }
  1         341  
29             ? 'Scalar::Util'->import(qw/blessed/)
30             : eval(q{
31             require B;
32             sub blessed ($) {
33             return undef unless length(ref($_[0]));
34             my $b = B::svref_2object($_[0]);
35             return undef unless $b->isa('B::PVMG');
36             my $s = $b->SvSTASH;
37             return $s->isa('B::HV') ? $s->NAME : undef;
38             }
39             });
40             };
41            
42             use overload
43 5 100   5   19 q(|) => sub { _apply($_[2] ? @_[1,0] : @_[0,1], "|") },
44 5 100   5   14 q(/) => sub { _apply($_[2] ? @_[1,0] : @_[0,1], "/") },
45 2 50   2   9 q(<<) => sub { _apply($_[2] ? @_[1,0] : @_[0,1], "<<") },
46 3 100   3   13 q(>>) => sub { _apply($_[2] ? @_[1,0] : @_[0,1], ">>") },
47 2     2   9 q(&{}) => sub { $_[0]->{code} },
48 0     0   0 q("") => sub { !!1 },
49 0     0   0 q(0+) => sub { !!1 },
50 0     0   0 q(bool)=> sub { !!1 },
51 1     1   1683 ;
  1         1028  
  1         22  
52            
53             sub _apply
54             {
55 15     15   25 my ($left, $right, $op) = @_;
56 15         12 my $self;
57            
58 15 100 66     119 if (blessed $left and $left->isa(__PACKAGE__))
    50 33        
59             {
60 7 50       14 croak ">>infix<< not supported" if $op eq "<<";
61 7         16 ($self = $left)->{right} = $right;
62             }
63             elsif (blessed $right and $right->isa(__PACKAGE__))
64             {
65 8 100       260 croak ">>infix<< not supported" if $op eq ">>";
66 7         17 ($self = $right)->{left} = $left;
67             }
68             else
69             {
70 0         0 croak "incorrect usage of infix operator";
71             }
72            
73 14 100       29 if (exists $self->{op})
74             {
75 7         24 my $combo = join "infix", sort $op, $self->{op};
76 7 100 100     35 unless ($combo eq '<>' or $combo eq '/infix/' or $combo eq '|infix|')
      100        
77             {
78 1         250 croak "$combo not supported";
79             }
80             }
81             else
82             {
83 7         11 $self->{op} = $op;
84             }
85            
86 13 100 66     86 if (exists $self->{left} and exists $self->{right})
87             {
88 6         20 return $self->{code}->($self->{left}, $self->{right});
89             }
90            
91 7         24 return $self;
92             }
93             }
94              
95             1;
96              
97             __END__