File Coverage

blib/lib/Module/AnyEvent/Helper.pm
Criterion Covered Total %
statement 65 75 86.6
branch 17 24 70.8
condition 12 20 60.0
subroutine 14 15 93.3
pod 4 4 100.0
total 112 138 81.1


line stmt bran cond sub pod time code
1             package Module::AnyEvent::Helper;
2              
3 9     9   173221 use strict;
  9         37  
  9         409  
4 9     9   85 use warnings;
  9         15  
  9         336  
5              
6 9     9   8525 use Try::Tiny;
  9         16091  
  9         601  
7 9     9   62 use AnyEvent;
  9         18  
  9         174  
8 9     9   44 use Carp;
  9         19  
  9         1812  
9              
10             # ABSTRACT: Helper module to make other modules AnyEvent-friendly
11             our $VERSION = 'v0.0.5'; # VERSION
12              
13             require Exporter;
14             our (@ISA) = qw(Exporter);
15             our (@EXPORT_OK) = qw(strip_async strip_async_all bind_scalar bind_array);
16              
17             sub _strip_async
18             {
19 9     9   35 my ($pkg, @func) = @_;
20 9         22 foreach my $func (@func) {
21 24 50       130 croak "$func does not end with _async" unless $func =~ /_async$/;
22 24         116 my $new_func = $func;
23 24         82 $new_func =~ s/_async$//;
24              
25 9     9   52 no strict 'refs'; ## no critic (ProhibitNoStrict)
  9         17  
  9         2041  
26 24         176 *{$pkg.'::'.$new_func} = sub {
27 37     37   1158077 shift->$func(@_)->recv;
28 24         98 };
29             }
30             }
31              
32             sub strip_async
33             {
34 0 0   0 1 0 shift if eval { $_[0]->isa(__PACKAGE__); };
  0         0  
35 0         0 my $pkg = caller;
36 0         0 _strip_async($pkg, @_);
37             }
38              
39             sub strip_async_all
40             {
41 9 100   9 1 1568 shift if eval { $_[0]->isa(__PACKAGE__); };
  9         126  
42 9         37 my $pkg = caller;
43 9         93 my %arg = @_;
44 9   100     70 $arg{-exclude} ||= [];
45 9         18 my %exclude = map { $_.'_async', 1 } @{$arg{-exclude}};
  1         5  
  9         38  
46 9     9   58 no strict 'refs'; ## no critic (ProhibitNoStrict)
  9         21  
  9         5743  
47 9 100 66     17 _strip_async($pkg, grep { /_async$/ && defined *{$pkg.'::'.$_}{CODE} && ! exists $exclude{$_} } keys %{$pkg.'::'});
  63         311  
  25         377  
  9         53  
48             }
49              
50             my $guard = sub {};
51              
52             sub bind_scalar
53             {
54 56 100   56 1 32803 shift if eval { $_[0]->isa(__PACKAGE__); };
  56         976  
55 56         179 my ($gcv, $lcv, $succ) = @_;
56              
57 56 50 33     554 if(!defined $lcv || ref($lcv) ne 'AnyEvent::CondVar') {
58 0         0 my $ret = $lcv;
59 0         0 $lcv = AE::cv;
60 0         0 $lcv->send($ret);
61             }
62 56 50       407 confess 'unexpected undef code reference' unless ref($succ) eq 'CODE';
63              
64             $lcv->cb(sub {
65 56     56   4191147 my $arg = shift;
66             try {
67 56         4307 my $ret = $succ->($arg);
68 54 100 66     1761 $gcv->send($ret) if ref($ret) ne 'CODE' || $ret != $guard;
69             } catch {
70 2         77 $gcv->croak($_);
71             }
72 56         787 });
  56         1127  
73 56         1167 $guard;
74             }
75              
76             sub bind_array
77             {
78 14 100   14 1 2692 shift if eval { $_[0]->isa(__PACKAGE__); };
  14         993  
79 14         110 my ($gcv, $lcv, $succ) = @_;
80              
81 14 50 33     146 if(!defined $lcv || ref($lcv) ne 'AnyEvent::CondVar') {
82 0         0 my $ret = $lcv;
83 0         0 $lcv = AE::cv;
84 0         0 $lcv->send($ret);
85             }
86 14 50       55 confess 'unexpected undef code reference' unless ref($succ) eq 'CODE';
87              
88             $lcv->cb(sub {
89 14     14   1098116 my $arg = shift;
90             try {
91 14         932 my @ret = $succ->($arg);
92 12 100 66     305 $gcv->send(@ret) if @ret != 1 || ref($ret[0]) ne 'CODE' || $ret[0] != $guard;
      66        
93             } catch {
94 2         65 $gcv->croak($_);
95             }
96 14         127 });
  14         296  
97 14         253 $guard;
98             }
99              
100             1;
101              
102             __END__