File Coverage

blib/lib/Promises.pm
Criterion Covered Total %
statement 44 54 81.4
branch 11 18 61.1
condition 3 5 60.0
subroutine 14 16 87.5
pod 5 5 100.0
total 77 98 78.5


line stmt bran cond sub pod time code
1             package Promises;
2             our $AUTHORITY = 'cpan:YANICK';
3             $Promises::VERSION = '1.03';
4             # ABSTRACT: An implementation of Promises in Perl
5              
6 11     11   457083 use strict;
  11         80  
  11         256  
7 11     11   44 use warnings;
  11         17  
  11         252  
8              
9 11     11   4223 use Promises::Deferred;
  11         21  
  11         642  
10             our $Backend = 'Promises::Deferred';
11              
12             our $WARN_ON_UNHANDLED_REJECT = 0;
13              
14 11         69 use Sub::Exporter -setup => {
15              
16             collectors => [
17             'backend' => \'_set_backend',
18             'warn_on_unhandled_reject' => \'_set_warn_on_unhandled_reject',
19             ],
20             exports => [qw[
21             deferred resolved rejected
22             collect collect_hash
23             ]]
24 11     11   5267 };
  11         111174  
25              
26             sub _set_warn_on_unhandled_reject {
27 2     2   224 my( undef, $arg ) = @_;
28              
29 2 50       7 if( $WARN_ON_UNHANDLED_REJECT = $arg->[0] ) {
30             # only brings the big guns if asked for
31              
32             *Promises::Deferred::DESTROY = sub {
33              
34 12 50   12   23 return unless $WARN_ON_UNHANDLED_REJECT;
35              
36 12         15 my $self = shift;
37              
38             return unless
39 12 100 100     18 $self->is_rejected and not $self->{_reject_was_handled};
40              
41 4         1026 require Data::Dumper;
42              
43 4         11056 my $dump =
44             Data::Dumper->new([$self->result])->Terse(1)->Dump;
45              
46 4         181 chomp $dump;
47 4         26 $dump =~ s/\n\s*/ /g;
48              
49             warn "Promise's rejection ", $dump,
50             " was not handled",
51 4 100       18 ($self->{_caller} ? ( ' at ', join ' line ', @{$self->{_caller}} ) : ()) , "\n";
  3         21  
52 2         13 };
53             }
54             }
55              
56             sub _set_backend {
57 0     0   0 my ( undef, $arg ) = @_;
58 0 0       0 my $backend = $arg->[0] or return;
59              
60 0 0       0 unless ( $backend =~ s/^\+// ) {
61 0         0 $backend = 'Promises::Deferred::' . $backend;
62             }
63 0         0 require Module::Runtime;
64 0   0     0 $Backend = Module::Runtime::use_module($backend) || return;
65 0         0 return 1;
66              
67             }
68              
69             sub deferred(;&) {
70 29     29 1 2068 my $promise = $Backend->new;
71              
72 29 50       62 if ( my $code = shift ) {
73 0         0 $promise->resolve;
74             return $promise->then(sub{
75 0     0   0 $code->($promise);
76 0         0 });
77             }
78              
79 29         61 return $promise;
80             }
81              
82 14     14 1 145 sub resolved { deferred->resolve(@_) }
83 1     1 1 9 sub rejected { deferred->reject(@_) }
84              
85             sub collect_hash {
86             collect(@_)->then( sub {
87             map {
88 3     3   6 my @values = @$_;
  14         16  
89 14 100       21 die "'collect_hash' promise returned more than one value: [@{[ join ', ', @values ]} ]\n"
  1         9  
90             if @values > 1;
91              
92 13 100       28 @values == 1 ? $values[0] : undef;
93             } @_ })
94 3     3 1 4 }
95              
96             sub collect {
97 8     8 1 23 my @promises = @_;
98              
99 8         14 my $all_done = resolved();
100              
101 8         13 for my $p ( @promises ) {
102 26         109 my @results;
103             $all_done = $all_done->then( sub {
104 26     26   41 @results = @_;
105 26         45 return $p;
106 26     26   118 } )->then(sub{ ( @results, [ @_ ] ) } );
  26         60  
107             }
108              
109 8         45 return $all_done;
110             }
111              
112             1;
113              
114             __END__