File Coverage

blib/lib/Async/Defer.pm
Criterion Covered Total %
statement 329 333 98.8
branch 127 130 97.6
condition 52 58 89.6
subroutine 42 42 100.0
pod 16 16 100.0
total 566 579 97.7


line stmt bran cond sub pod time code
1             package Async::Defer;
2              
3 18     18   490766 use 5.012;
  18         82  
  18         792  
4 18     18   104 use warnings;
  18         38  
  18         496  
5 18     18   102 use strict;
  18         34  
  18         649  
6 18     18   96 use Carp;
  18         45  
  18         1919  
7              
8 18     18   18712 use version; our $VERSION = qv('0.9.5'); # REMINDER: update Changes
  18         49560  
  18         114  
9              
10             # REMINDER: update dependencies in Makefile.PL
11 18     18   1867 use Scalar::Util qw( refaddr );
  18         38  
  18         2594  
12              
13             ## no critic (ProhibitBuiltinHomonyms)
14              
15 18     18   106 use constant NOT_RUNNING=> -1;
  18         32  
  18         1278  
16 18     18   103 use constant OP_CODE => 1;
  18         53  
  18         762  
17 18     18   86 use constant OP_DEFER => 2;
  18         56  
  18         790  
18 18     18   303 use constant OP_IF => 3;
  18         30  
  18         810  
19 18     18   83 use constant OP_ELSE => 4;
  18         41  
  18         1325  
20 18     18   122 use constant OP_ENDIF => 5;
  18         39  
  18         815  
21 18     18   83 use constant OP_WHILE => 6;
  18         51  
  18         821  
22 18     18   96 use constant OP_ENDWHILE=> 7;
  18         34  
  18         857  
23 18     18   83 use constant OP_TRY => 8;
  18         30  
  18         897  
24 18     18   80 use constant OP_CATCH => 9;
  18         31  
  18         714  
25 18     18   79 use constant OP_FINALLY => 10;
  18         29  
  18         697  
26 18     18   118 use constant OP_ENDTRY => 11;
  18         39  
  18         100901  
27              
28             my %SELF;
29              
30              
31             sub new {
32 195     195 1 1007655 my ($class) = @_;
33 195         507 my $this = bless {}, $class;
34 195         1651 $SELF{refaddr $this} = {
35             parent => undef, # parent Defer object, if any
36             opcode => [], # [[OP_CODE,$sub], [OP_TRY], ...]
37             pc => NOT_RUNNING,# point to _CURRENT_ opcode, if any
38             iter => [], # [[1,$outer_while_pc], [8,$inner_while_pc], ...]
39             findone => undef, # undef or ['continue'] or ['break'] or ['throw',$err]
40             };
41 195         467 return $this;
42             }
43              
44             sub DESTROY {
45 62     62   496322 my ($this) = @_;
46 62         742 delete $SELF{refaddr $this};
47 62         1547 return;
48             }
49              
50             sub clone {
51 7     7 1 21 my ($this) = @_;
52 7         22 my $self = $SELF{refaddr $this};
53              
54 7         17 my $clone = __PACKAGE__->new();
55 7         24 my $clone_self = $SELF{refaddr $clone};
56              
57 7         8 $clone_self->{opcode} = [ @{ $self->{opcode} } ];
  7         19  
58 7         12 %{$clone} = %{$this};
  7         17  
  7         23  
59 7         20 return $clone;
60             }
61              
62             sub iter {
63 203     203 1 666 my ($this) = @_;
64 203         433 my $self = $SELF{refaddr $this};
65              
66 203 100       183 if (!@{ $self->{iter} }) {
  203         465  
67 5         98 croak 'iter() can be used only inside while';
68             }
69              
70 198         849 return $self->{iter}[-1][0];
71             }
72              
73             sub _add {
74 706     706   1174 my ($this, $op, @params) = @_;
75 706         1838 my $self = $SELF{refaddr $this};
76              
77 706 100       1672 if ($self->{pc} != NOT_RUNNING) {
78 8         131 croak 'unable to modify while running';
79             }
80              
81 698         761 push @{ $self->{opcode} }, [ $op, @params ];
  698         1806  
82 698         2002 return $this;
83             }
84              
85             sub do {
86 297     297 1 5986 my ($this, $task, @more_tasks) = @_;
87 297 100       683 if(@more_tasks){
88 3         8 for ($task, @more_tasks) {
89 15         30 $this->do($_);
90             }
91 3         11 return $this;
92             }
93 294         505 given (ref $task) {
94 294         611 when ('CODE') {
95 198         414 return $this->_add(OP_CODE, $task);
96             }
97 96         150 when (__PACKAGE__) {
98 76         159 return $this->_add(OP_DEFER, $task);
99             }
100 20         35 when ('ARRAY') {
101 10         20 my %task = map { $_ => $task->[$_] } 0 .. $#{ $task };
  23         65  
  10         26  
102 10         47 return $this->_add(OP_CODE, _do_batch(1, %task));
103             }
104 10         23 when ('HASH') {
105 9         14 return $this->_add(OP_CODE, _do_batch(0, %{ $task }));
  9         35  
106             }
107 1         1 default {
108 1         25 croak 'require CODE/Defer object or ARRAY/HASH in first param'
109             }
110             }
111             }
112              
113             sub _do_batch {
114 19     19   50 my ($is_array, %task) = @_;
115              
116             # Isolate each task in own Defer object to guarantee they won't be
117             # surprised by shared state.
118 19         50 for my $key (keys %task) {
119 43         53 my $task;
120 43         77 given (ref $task{$key}) {
121 43         72 when ('CODE') {
122 39         77 $task = __PACKAGE__->new();
123 39         99 $task->do( $task{$key} );
124             }
125 4         9 when (__PACKAGE__) {
126 4         15 $task = $task{$key}->clone();
127             }
128 0         0 default {
129 0 0       0 my $pos = $is_array ? $key+1 : "{$key}";
130 0         0 croak 'require CODE/Defer object in param '.$pos;
131             }
132             }
133 43         98 $task{$key} = $task;
134             }
135              
136             return sub{
137 19     19   45 my ($d, @taskparams) = @_;
138 14         38 my %taskparams
139             = !$is_array ? (@taskparams)
140 19 100       65 : (map { ($_ => $taskparams[$_]) } 0 .. $#taskparams);
141              
142 19 100       53 if (!keys %task) {
143 2         6 return $d->done();
144             }
145              
146 17         38 my %taskresults = map { $_ => undef } keys %task;
  43         111  
147 17         86 for my $key (sort keys %task) { # sort just to simplify testing
148 43         106 my $t = __PACKAGE__->new();
149 43         92 $t->try();
150 43         109 $t->do( $task{$key} );
151             $t->catch(
152             qr/.*/ms => sub{
153 2         5 my ($t,$err) = @_; ## no critic (ProhibitReusedNames)
154 2         5 $t->{err} = $err;
155 2         7 $t->done();
156             },
157             FINALLY => sub{
158 19         35 my ($t, @result) = @_; ## no critic (ProhibitReusedNames)
159 19   100     235 $taskresults{$key} = $t->{err} // \@result;
160 19 100       45 if (!grep {!defined} values %taskresults) {
  77         158  
161             my @taskresults
162 11         31 = !$is_array ? %taskresults
163 5 100       27 : map { $taskresults{$_-1} } 1 .. keys %taskresults;
164 5         18 $d->done(@taskresults);
165             }
166 19         80 return $t->done();
167             },
168 43         459 );
169 43 100       57 $t->run( undef, @{ $taskparams{$key} || [] } );
  43         178  
170             }
171 19         175 };
172             }
173              
174             sub if {
175 23     23 1 1788 my ($this, $code) = @_;
176 23 100 66     139 if (!$code || ref $code ne 'CODE') {
177 1         25 croak 'require CODE in first param';
178             }
179 22         49 return $this->_add(OP_IF, $code);
180             }
181              
182             sub else {
183 15     15 1 1303 my ($this) = @_;
184 15         32 return $this->_add(OP_ELSE);
185             }
186              
187             sub end_if {
188 22     22 1 1219 my ($this) = @_;
189 22         61 return $this->_add(OP_ENDIF);
190             }
191              
192             sub while {
193 21     21 1 1265 my ($this, $code) = @_;
194 21 100 66     154 if (!$code || ref $code ne 'CODE') {
195 1         25 croak 'require CODE in first param';
196             }
197 20         123 return $this->_add(OP_WHILE, $code);
198             }
199              
200             sub end_while {
201 19     19 1 925 my ($this) = @_;
202 19         52 return $this->_add(OP_ENDWHILE);
203             }
204              
205             sub try {
206 87     87 1 999 my ($this) = @_;
207 87         193 return $this->_add(OP_TRY);
208             }
209              
210             sub catch {
211 91     91 1 4512 my ($this, @param) = @_;
212 91 100       341 if (2 > @param) {
    100          
213 2         31 croak 'require at least 2 params';
214             } elsif (@param % 2) {
215 1         8 croak 'require even number of params';
216             }
217              
218 88         123 my ($finally, @catch);
219 88         278 while (my ($cond, $code) = splice @param, 0, 2) {
220 146 100       284 if ($cond eq 'FINALLY') {
221 62   66     358 $finally ||= $code;
222             } else {
223 84         295 push @catch, $cond, $code;
224             }
225             }
226              
227 88 100       190 if (@catch) {
228 80         176 $this->_add(OP_CATCH, @catch);
229             }
230 87 100       194 if ($finally) {
231 61         132 $this->_add(OP_FINALLY, $finally);
232             }
233 87         250 return $this->_add(OP_ENDTRY);
234             }
235              
236             sub _check_stack {
237 244     244   302 my ($self) = @_;
238 244         257 my @stack;
239 244         803 my %op_open = (
240             OP_IF() => 'end_if()',
241             OP_WHILE() => 'end_while()',
242             OP_TRY() => 'catch()',
243             );
244 244         1261 my %op_close = (
245             OP_ENDIF() => [ OP_IF, 'end_if()' ],
246             OP_ENDWHILE() => [ OP_WHILE, 'end_while()' ],
247             OP_ENDTRY() => [ OP_TRY, 'catch()' ],
248             );
249 244         395 my $extra = 0;
250 244         388 for (my $i = 0; $i < @{ $self->{opcode} }; $i++) {
  1259         3089  
251 1023         2605 my ($op) = @{ $self->{opcode}[ $i ] };
  1023         1667  
252              
253 1023 100 100     3742 if ($op == OP_CATCH || $op == OP_FINALLY) {
254 188         200 $extra++;
255             }
256              
257 1023 100       3364 if ($op_open{$op}) {
    100          
    100          
258 198         903 push @stack, [$op,0]; # second number is counter for seen OP_ELSE
259             }
260             elsif ($op_close{$op}) {
261 192         189 my ($close_op, $close_func) = @{ $op_close{$op} };
  192         304  
262 192 100 100     994 if (@stack && $stack[-1][0] == $close_op) {
263 186         405 pop @stack;
264             } else {
265 6         92 croak 'unexpected '.$close_func.' at operation '.($i+1-$extra);
266             }
267             }
268             elsif ($op == OP_ELSE) {
269 32 100 66     153 if (!(@stack && $stack[-1][0] == OP_IF)) {
    100          
270 1         12 croak 'unexpected else() at operation '.($i+1-$extra);
271             }
272             elsif ($stack[-1][1]) {
273 1         13 croak 'unexpected double else() at operation '.($i+1-$extra);
274             }
275 30         45 $stack[-1][1]++;
276             }
277             }
278 236 100       493 if (@stack) {
279 5         59 croak 'expected '.$op_open{ $stack[-1][0] }.' at end';
280             }
281 231         1087 return;
282             }
283              
284             sub run {
285 247     247 1 48184 my ($this, $d, @result) = @_;
286 247         634 my $self = $SELF{refaddr $this};
287              
288 247         508 my %op_stmt = map {$_=>1} OP_CODE, OP_DEFER, OP_FINALLY;
  741         1843  
289 247 100       414 if (!grep {$op_stmt{ $_->[0] }} @{ $self->{opcode} }) {
  1036         2140  
  247         1292  
290 2         24 croak 'no operations to run, use do() first';
291             }
292 245 100       621 if ($self->{pc} != NOT_RUNNING) {
293 1         16 croak 'already running';
294             }
295 244         454 _check_stack($self);
296              
297 231 100       503 if(ref($d) eq 'CODE') {
298 1         1 my $callback = $d;
299 1         4 $d = __PACKAGE__->new();
300             $d->do(
301             sub {
302 1     1   2 my ($defer, @results) = @_;
303 1         3 $callback->(@results);
304 1         6 $defer->done;
305             }
306 1         5 );
307             }
308              
309 231         324 $self->{parent} = $d;
310 231         694 $this->done(@result);
311 228         984 return;
312             }
313              
314             sub _op {
315 2201     2201   2970 my ($self) = @_;
316 2201         2186 my ($op, @params) = @{ $self->{opcode}[ $self->{pc} ] };
  2201         4881  
317 2201 100       6708 return wantarray ? ($op, @params) : $op;
318             }
319              
320             sub done {
321 733     733 1 30424 my ($this, @result) = @_;
322 733         1713 my $self = $SELF{refaddr $this};
323              
324             # If OP_FINALLY was called while processing continue(), break() or throw(),
325             # and it has finished with done() - continue with continue/break/throw by
326             # calling them _again_ instead of done().
327 733 100       1989 if ($self->{findone}) {
328 23         22 my ($method, @param) = @{ $self->{findone} };
  23         72  
329 23         101 return $this->$method(@param);
330             }
331              
332 710         1139 while (++$self->{pc} <= $#{ $self->{opcode} }) {
  1082         2943  
333 921         1626 my ($opcode, @param) = _op($self);
334              
335             # @result received from previous opcode will be available to next
336             # opcode only if these opcodes stay one-after-one without any
337             # other opcodes between them (like OP_IF, for example).
338             # Only exception is (no-op) OP_TRY, OP_CATCH and OP_ENDTRY.
339             # This limitation should help user to avoid subtle bugs.
340 921         1371 given ($opcode) {
341 921         1574 when (OP_CODE) {
342 361         1196 return $param[0]->($this, @result);
343             }
344 560         786 when (OP_DEFER) {
345 76         269 return $param[0]->run($this, @result);
346             }
347 484         546 when (OP_FINALLY) {
348 40         276 return $param[0]->($this, @result);
349             }
350 444         1175 when ([OP_TRY,OP_CATCH,OP_ENDTRY]) {
351 215         1157 next;
352             }
353             }
354 229         372 @result = ();
355              
356 229         246 given ($opcode) {
357 229         241 when (OP_IF) {
358             # true - do nothing (i.e. just move to next opcode)
359             # false - skip to nearest OP_ELSE or OP_ENDIF
360 52 100       108 if (!$param[0]->( $this )) {
361 28         77 my $stack = 0;
362 28         40 while (++$self->{pc} <= $#{ $self->{opcode} }) {
  117         241  
363 117         175 my $op = _op($self);
364 117 100 100     557 $op == OP_ELSE && !$stack ? last
    100 100        
    100          
    100          
365             : $op == OP_ENDIF && !$stack ? last
366             : $op == OP_IF ? $stack++
367             : $op == OP_ENDIF ? $stack--
368             : next;
369             }
370             }
371             }
372 177         234 when (OP_ELSE) {
373             # skip this OP_ELSE branch to nearest OP_ENDIF
374 11         13 my $stack = 0;
375 11         14 while (++$self->{pc} <= $#{ $self->{opcode} }) {
  34         69  
376 34         56 my $op = _op($self);
377 34 100 100     134 $op == OP_ENDIF && !$stack ? last
    100          
    100          
378             : $op == OP_IF ? $stack++
379             : $op == OP_ENDIF ? $stack--
380             : next;
381             }
382             }
383 166         190 when (OP_WHILE) {
384             # We can "enter" OP_WHILE in two cases - for the first time,
385             # OR because of continue() called inside this OP_WHILE.
386 98 100 100     127 if (!@{$self->{iter}} || $self->{iter}[-1][1] != $self->{pc}) {
  98         490  
387 33         62 push @{ $self->{iter} }, [ 1, $self->{pc} ];
  33         87  
388             }
389             # We now already "inside" this OP_WHILE, so we can use break()
390             # to exit _this_ OP_WHILE.
391 98 100       300 if (!$param[0]->( $this )) {
392 23         114 return $this->break();
393             }
394             }
395 68         103 when (OP_ENDWHILE) {
396             # We now still "inside" current OP_WHILE, so we can use continue()
397             # to repeat _this_ OP_WHILE.
398 49         180 return $this->continue();
399             }
400             }
401             }
402              
403 161         247 $self->{pc} = NOT_RUNNING;
404 161 100       1407 if ($self->{parent}) {
405 53         636 return $self->{parent}->done(@result);
406             }
407              
408             # If we're here, done() was called by last opcode, and this is
409             # top-level Defer object, nothing more to do - STOP.
410             }
411              
412             # Before executing continue/break logic we have to find and execute all
413             # OP_FINALLY for all already open OP_TRY blocks within this OP_WHILE.
414             # So, this helper skip opcodes inside this OP_WHILE until it found
415             # either OP_FINALLY or OP_ENDWHILE or last opcode.
416             sub _skip_while {
417 132     132   158 my ($self) = @_;
418              
419             # 1. continue() can be called exactly on OP_ENDWHILE (by done())
420             # 2. continue/break can be called by last opcode
421             # In both cases we shouldn't do anything (including moving {pc} forward).
422 132 100 66     198 if (_op($self) == OP_ENDWHILE || $self->{pc} == $#{ $self->{opcode} }) {
  83         282  
423 49         69 return;
424             }
425              
426 83         130 my $stack = 0;
427 83         82 my $trystack = 0;
428 83         111 while (++$self->{pc} < $#{ $self->{opcode} }) {
  333         861  
429 294         444 my $op = _op($self);
430 294 100 100     1855 $op == OP_ENDWHILE && !$stack ? last
    100 100        
    100 100        
    100          
    100          
    100          
431             : $op == OP_WHILE ? $stack++
432             : $op == OP_ENDWHILE ? $stack--
433             : $op == OP_TRY ? $trystack++
434             : $op == OP_ENDTRY && $trystack ? $trystack--
435             : $op == OP_FINALLY && !$trystack ? last
436             : next;
437             }
438              
439 83         118 return;
440             }
441              
442             sub continue {
443 88     88 1 181 my ($this) = @_;
444 88         195 my $self = $SELF{refaddr $this};
445              
446             # Any next call to continue/break/throw cancels current continue/break/throw (if any).
447 88         115 $self->{findone} = undef;
448              
449 88         157 _skip_while($self);
450 88         145 my ($op, @param) = _op($self);
451 88 100       188 if ($op == OP_FINALLY) {
452             # If OP_FINALLY ends with done() - call continue() again instead.
453 21         40 $self->{findone} = ['continue'];
454 21         58 return $param[0]->($this);
455             }
456              
457             # We now at OP_ENDWHILE, rewind to corresponding OP_WHILE.
458 67         81 my $stack = 0;
459 67         206 while (--$self->{pc} > 0) {
460 444         634 $op = _op($self);
461 444 100 100     1917 $op == OP_WHILE && !$stack ? last
    100          
    100          
462             : $op == OP_ENDWHILE ? $stack++
463             : $op == OP_WHILE ? $stack--
464             : next;
465             }
466              
467             # If continue was called outside OP_WHILE there is no iteration number.
468 67 100       67 if (@{ $self->{iter} }) {
  67         183  
469 65         108 $self->{iter}[-1][0]++;
470             }
471              
472             # Step one opcode back because done() will move one opcode forward
473             # and so process this OP_WHILE.
474 67         90 --$self->{pc};
475 67         227 return $this->done();
476             }
477              
478             sub break {
479 44     44 1 103 my ($this) = @_;
480 44         138 my $self = $SELF{refaddr $this};
481              
482             # Any next call to continue/break/throw cancels current continue/break/throw (if any).
483 44         64 $self->{findone} = undef;
484              
485 44         110 _skip_while($self);
486 44         78 my ($op, @param) = _op($self);
487 44 100       110 if ($op == OP_FINALLY) {
488             # If OP_FINALLY ends with done() - call break() again instead.
489 13         26 $self->{findone} = ['break'];
490 13         35 return $param[0]->($this);
491             }
492              
493             # We now at OP_ENDWHILE.
494 31         34 pop @{ $self->{iter} };
  31         52  
495 31         120 return $this->done();
496             }
497              
498             sub throw {
499 58     58 1 259 my ($this, $err) = @_;
500 58         147 my $self = $SELF{refaddr $this};
501 58   100     194 $err //= q{};
502              
503             # Any next call to continue/break/throw cancels current continue/break/throw (if any).
504 58         87 $self->{findone} = undef;
505              
506             # If throw() was called by break opcode in this OP_TRY (either OP_FINALLY,
507             # or OP_CATCH if there no OP_FINALLY in this OP_TRY), then we should look
508             # for handler in outer OP_TRY, not in this one.
509             # So we set $stack=1 to skip over current OP_TRY's OP_ENDTRY.
510 58 100       73 my ($nextop) = @{ $self->{opcode}[ $self->{pc} + 1 ] || [] };
  58         204  
511 58 100 100     245 my $stack = $nextop && $nextop == OP_ENDTRY ? 1 : 0;
512             # Skip until OP_CATCH or OP_FINALLY in current OP_TRY block.
513             # If while skipping we exit some OP_WHILE(s) - pop their iterators.
514 58         147 while (++$self->{pc} <= $#{ $self->{opcode} }) {
  81         282  
515 75         132 my $op = _op($self);
516 0         0 $op == OP_CATCH && !$stack ? last
517             : $op == OP_FINALLY && !$stack ? last
518             : $op == OP_TRY ? $stack++
519             : $op == OP_ENDTRY ? $stack--
520 3         8 : $op == OP_WHILE ? push @{ $self->{iter} }, [ 1, $self->{pc} ]
521 75 100 100     412 : $op == OP_ENDWHILE ? pop @{ $self->{iter} }
    50 66        
    100          
    100          
    100          
    100          
522             : next;
523             }
524              
525 58 100       116 if ($self->{pc} > $#{ $self->{opcode} }) {
  58         226  
526 6 100       19 if ($self->{parent}) {
527 4         25 return $self->{parent}->throw($err);
528             } else {
529 2         41 croak 'uncatched exception in Defer: '.$err;
530             }
531             }
532              
533 52         153 my ($op, @param) = _op($self);
534 52 100       154 if ($op == OP_CATCH) {
535 44         145 while (my ($cond, $code) = splice @param, 0, 2) {
536 49 100       299 if ($err =~ /$cond/ms) {
537 39         110 return $code->($this, $err);
538             }
539             }
540             # Re-throw exception if no one regex in this OP_CATCH match it.
541 5         27 return $this->throw($err);
542             }
543             else { # OP_FINALLY
544             # If OP_FINALLY ends with done() - call throw($err) again instead.
545 8         47 $self->{findone} = ['throw', $err];
546 8         21 return $param[0]->($this, $err);
547             }
548             }
549              
550              
551             1; # Magic true value required at end of module
552             __END__
553              
554             =encoding utf8
555              
556             =head1 NAME
557              
558             Async::Defer - VM to write and run async code in usual sync-like way
559              
560              
561             =head1 SYNOPSIS
562              
563             use Async::Defer;
564              
565             # ... CREATE
566              
567             my $defer = Async::Defer->new();
568             my $defer2 = $defer->clone();
569              
570             # ... SETUP
571              
572             $defer->do(sub{
573             my ($d, @param) = @_;
574             # run sync/async code which MUST end with one of:
575             # $d->done(@result);
576             # $d->throw($error);
577             # $d->continue();
578             # $d->break();
579             });
580              
581             $defer->if(sub{ my $d=shift; return 1 });
582              
583             $defer->try();
584              
585             $defer->do($defer2);
586              
587             $defer->catch(
588             qr/^io:/ => sub{
589             my ($d,$err) = @_;
590             # end with $d->done/throw/continue/break
591             },
592             qr/.*/ => sub{ # WILL CATCH ALL EXCEPTIONS
593             my ($d,$err) = @_;
594             # end with $d->done/throw/continue/break
595             },
596             FINALLY => sub{
597             my ($d,$err,@result) = @_;
598             # end with $d->done/throw/continue/break
599             },
600             );
601              
602             $defer->else();
603              
604             $defer->while(sub{ my $d=shift; return $d->iter() <= 3 });
605              
606             $defer->do(sub{
607             my ($d) = @_;
608             # may access $d->iter() here
609             # end with $d->done/throw/continue/break
610             });
611              
612             $defer->end_while();
613              
614             $defer->end_if();
615              
616             $defer->{anyvar} = 'anyval';
617              
618             # ... START
619              
620             $defer->run();
621              
622              
623             =head1 DESCRIPTION
624              
625             B<WARNING: This is experimental code, public interface may change.>
626              
627             This module's goal is to simplify writing complex async event-based code,
628             which usually mean huge amount of callback/errback functions, very hard to
629             support. It was initially inspired by Python/Twisted's
630             L<Deferred|http://twistedmatrix.com/documents/10.1.0/core/howto/defer.html>
631             object, but go further and provide virtual machine which allow you to
632             write/define complete async program (which consists of many
633             callback/errback) in sync way, just like you write usual non-async
634             programs.
635              
636             Main idea is simple. For example, if you've this non-async code:
637              
638             $var = fetch_val();
639             process_val( $var );
640              
641             and want to make C<fetch_val()> async, you usually do something like this:
642              
643             fetch_val( cb => \&value_fetched );
644             sub value_fetched {
645             my ($var) = @_;
646             process_val( $var );
647             }
648              
649             With Async::Defer you will split initial non-async code in sync parts (usually
650             this mean - split on assignment operator):
651              
652             ### 1
653             fetch_val();
654             ### 2
655             $var =
656             process_val( $var );
657              
658             then wrap each part in separate anon sub and add Defer object to join
659             these parts together:
660              
661             $d = Async::Defer->new();
662             $d->do(sub{
663             my ($d) = @_;
664             fetch_val( $d ); # will call $d->done('…result…') when done
665             });
666             $d->do(sub{
667             my ($d, $var) = @_;
668             process_val( $var );
669             $d->done(); # this sub is sync, it call done() immediately
670             });
671             $d->run();
672              
673             These anon subs are similar to I<statements> in perl. Between these
674             I<statements> you can use I<flow control> operators like C<if()>,
675             C<while()> and C<try()>/C<catch()>. And inside I<statements> you can
676             control execution flow using C<done()>, C<throw()>, C<continue()>
677             and C<break()> operators when current async function will finish and
678             will be ready to go to the continue step.
679             Finally, you can use Async::Defer object to keep your I<local variables> -
680             this object is empty hash, and you can create any keys in it.
681             Single Defer object described this way is sort of single I<function>.
682             And it's possible to I<call> another functions by using another Defer
683             object as parameter for C<do()> instead of usual anon sub.
684              
685             While you can use both sync and async sub in C<do()>, they all B<MUST>
686             call one of C<done()>, C<throw()>, C<continue()> or C<break()> when they finish
687             their work, and do this B<ONLY ONCE>. This is Defer's way to proceed from
688             one step to another, and if not done right Defer object's behaviour is
689             undefined!
690              
691              
692             =head2 PERSISTENT STATE, LOCAL VARIABLES and SCOPE
693              
694             There are several ways to implement this, and it's unclear yet which
695             way is the best. We can implement full-featured stack with local variables
696             similar to perl's C<local> using getter/setter methods; we can fill called
697             Defer objects with copy of all keys in parent Defer object (so called
698             object will have full read-only access to parent's scalar data, and read/write
699             access to parent's reference data types); we can do nothing and let user
700             manually send all needed data to called Defer object as params and get
701             data back using returned values (by C<done()> or C<throw()>).
702              
703             In current implementation we do nothing, so here is some ways to go:
704              
705             ### @results = another_defer(@params)
706             $d->do(sub{
707             my ($d) = @_;
708             my @params_for_another_defer = (…);
709             $d->done(@params_for_another_defer);
710             });
711             $d->do($another_defer);
712             $d->do(sub{
713             my ($d, @results_from_another_defer) = @_;
714             ...
715             $d->done();
716             });
717              
718             ### share some local variables with $another_defer
719             $d->do(sub{
720             my ($d) = @_;
721             $d->{readonly} = $scalar;
722             $d->{readwrite} = $ref_to_something;
723             $another_defer->{readonly} = $d->{readonly};
724             $another_defer->{readwrite} = $d->{readwrite};
725             $d->done();
726             });
727             $d->do($another_defer);
728             $d->do(sub{
729             my ($d) = @_;
730             # $d->{readwrite} here may be modifed by $another_defer
731             $d->done();
732             });
733              
734             ### share all variables with $another_defer (run it manually)
735             $d->do(sub{
736             my ($d) = @_;
737             %$another_defer = %$d;
738             $another_defer->run($d);
739             });
740             $d->do(sub{
741             my ($d) = @_;
742             # all reference-type keys in $d may be modifed by $another_defer
743             $d->done();
744             });
745              
746             If you want to reuse same Defer object several times, then you should keep
747             in mind: keys created inside this object on first run won't be automatically
748             removed, so on second and continue runs it will see internal data left by
749             previous runs. This may or may not be desirable behaviour. In later case
750             you should use C<clone()> and run only clones of original object (clones are
751             created using C<%$clone=%$orig>, so they share only reference-type keys
752             which exists in original Defer):
753              
754             $d->do( $another_defer->clone() );
755             $d->do( $another_defer->clone() );
756              
757             =head2 NESTED DEFERS
758              
759             Async::Defer objects can be nested, and there are two ways to do it.
760              
761             One way is to add a child defer to the parent defer using C<do()> method.
762              
763             my $cd = Async::Defer->new();
764            
765             ## setup the child defer.
766             $cd->do( ... );
767              
768             ## parent defer
769             my $pd = Async::Defer->new();
770             $pd->do( ... );
771             $pd->do(sub {
772             my $d = shift;
773             ...;
774             $d->done( @arguments_for_child_defer );
775             });
776             ## run the child defer
777             $pd->do($cd);
778             $pd->do(sub {
779             my ($d, @results_from_child_defer) = @_;
780             ...;
781             });
782              
783             The other way is to call C<run()> on the child defer with its first
784             argument being the parent defer. This is very useful when you dynamically
785             create the child defer in statements of the parent defer.
786              
787             ## parent defer
788             my $pd = Async::Defer->new();
789             $pd->do(sub {
790             my ($d, @args) = @_;
791            
792             ## create the child defer in the statement
793             my $cd = Async::Defer->new();
794            
795             ## setup the child defer
796             $cd->do( ... );
797            
798             ## run() the child.
799             ## You do not have to call $d->done explicitly,
800             ## because the flow continues from the child to the parent.
801             $cd->run($d, @argments_for_child_defer);
802             });
803             $pd->do(sub {
804             my ($d, @results_from_child_defer) = @_;
805             ...;
806             });
807              
808              
809             =head1 EXPORTS
810              
811             Nothing.
812              
813              
814             =head1 INTERFACE
815              
816             =over
817              
818             =item new()
819              
820             Create and return Async::Defer object.
821              
822             =item clone()
823              
824             Clone existing Async::Defer object and return clone.
825              
826             Clone will have same I<program> (I<STATEMENTS> and I<OPERATORS> added to
827             original object) and same I<local variables> (non-deep copy of orig object
828             keys using C<%$clone=%$orig>). After cloning these two objects can be
829             modified (by adding new I<STATEMENTS>, I<OPERATORS> and modifying variables)
830             independently.
831              
832             It's possible to C<clone()> object which is running right now, cloned object
833             will not be in running state - this is safe way to C<run()> objects which may
834             or may not be already running.
835              
836             =item run( [ $parent_defer, @params ] )
837              
838             =item run( [ \&callback, @params ] )
839              
840             Start executing object's current I<program>, which must be defined first by
841             adding at least one I<STATEMENT> (C<do()> or C<<catch(FINALLY=>sub{})>>)
842             to this object.
843              
844             Usually while C<run()> only first I<STATEMENT> will be executed (with optional
845             C<@params> in parameters). It will just start some async function and
846             returns, and C<run()> will returns immediately after this too. Actual
847             execution of this object will continue when started async function will
848             finish (usually after Timer or I/O event) and call this object's C<done()>,
849             C<break()>, C<continue()> or C<throw()> methods.
850              
851             It's possible to make all I<STATEMENTS> sync - in this case full I<program>
852             will be executed before returning from C<run()> - but this has no real sense
853             because you don't need Defer object for sync programs.
854              
855             If C<run()> used to start top-level I<program> (i.e. without C<$parent_defer>
856             parameter), then there will be no I<return value> at end of I<program> -
857             after break I<STATEMENT> in this object will call C<done()> nothing else will
858             happens and any parameters of that break C<done()> call will be ignored.
859             If this Defer object was started as part of another I<program> (i.e. it was
860             added there using C<do()> or just manually executed from some I<STATEMENT> with
861             defined C<$parent_defer> parameter), then it I<return value> will be delivered
862             to continue I<STATEMENT> in C<$parent_defer> object (See L</"NESTED DEFERS">).
863              
864             The first argument for C<run()> may also be a subroutine reference (C<\&callback>).
865             In this case, the callback is called after break I<STATEMENT> in this object.
866             The arguments for the callback are the results of the break I<STATEMENT>.
867             Any value returned from C<\&callback> will be ignored.
868              
869             =item iter()
870              
871             This method available only inside C<while()> - both in C<while()>'s
872             C<\&conditional> argument and C<while()>'s body I<STATEMENTS>. It return
873             current iteration number for nearest C<while()>, starting from 1.
874              
875             # this loop will execute 3 times:
876             $d->while(sub{ shift->iter() <= 3 });
877             $d->do(sub{
878             my ($d) = @_;
879             printf "Iteration %d\n", $d->iter();
880             $d->done();
881             });
882             $d->end_while();
883              
884             =back
885              
886             =head2 STATEMENTS and OPERATORS
887              
888             All I<STATEMENTS> methods return the Async::Defer object,
889             so that you can chain method calls.
890              
891             =over
892              
893             =item do( \&sync_or_async_code, … )
894              
895             =item do( $child_defer, … )
896              
897             Add I<STATEMENT> to this object's I<program>.
898              
899             When this I<STATEMENT> should be executed, C<\&sync_or_async_code>
900             (or C<$child_defer>'s first I<STATEMENT>) will be called with these params:
901              
902             ( $defer_object, @optional_results_from_previous_STATEMENT )
903              
904             C<do()> accepts multiple arguments. Those I<STATEMENT>s are added to the object
905             in that order, and can be mix of any types - i.e. it's same as call C<do()>
906             sequentially multiple times providing these arguments one-by-one.
907              
908             do(
909             \&code,
910             $defer,
911             [$defer1, $defer2, \&code3],
912             {
913             task1 => $defer4,
914             task2 => \&code5,
915             },
916             \&more_code,
917             …
918             );
919              
920             =item do( [\&sync_or_async_code, $child_defer, …], … )
921              
922             =item do( {task1=>\&sync_or_async_code, task2=>$child_defer, …}, … )
923              
924             Add one I<STATEMENT> to this object's I<program>.
925              
926             When this I<STATEMENT> should be executed, all these tasks will be started
927             simultaneously (Defer objects using C<clone()> and C<run()>, code by
928             transforming into new Defer object and then also C<run()>).
929             This I<program> will continue only after all these tasks will be finished
930             (either with C<done()> or C<throw()>).
931              
932             It's possible to provide params individually for each of these tasks and
933             receive results/error returned by each of these tasks, but actual syntax
934             depends on how these tasks was named - by id (ARRAY) or by name (HASH):
935              
936             $d->do(sub{
937             my ($d) = @_;
938             $d->done(
939             ['param1 for task1', 'param2 for task1'],
940             ['param1 for task2'],
941             [undef, 'param2 for task3'],
942             # no params for task4,task5,…
943             );
944             });
945             $d->do([ $d_task1, $d_task2, $d_task3, $d_some, $d_some ]);
946             $d->do(sub{
947             my ($d, @taskresults) = @_;
948             my $id = 1;
949             if (ref $taskresults[$id-1]) {
950             print "task $id results:", @{ $taskresults[$id-1] };
951             } else {
952             print "task $id throw error:", $taskresults[$id-1];
953             }
954             });
955              
956             $d->do(sub{
957             my ($d) = @_;
958             $d->done(
959             task1 => ['param1 for task1', 'param2 for task1'],
960             task2 => ['param1 for task2'],
961             task3 => [undef, 'param2 for task3'],
962             # no params for task4,task5,…
963             );
964             });
965             $d->do({
966             task1 => $d_task1,
967             task2 => $d_task2,
968             task3 => $d_task3,
969             task4 => $d_some,
970             task5 => $d_some,
971             });
972             $d->do(sub{
973             my ($d, %taskresults) = @_;
974             if (ref $taskresults{task1}) {
975             print "task1 results:", @{ $taskresults{task1} };
976             } else {
977             print "task1 throw error:", $taskresults{task1};
978             }
979             });
980              
981             =item if( \&conditional )
982              
983             =item else()
984              
985             =item end_if()
986              
987             Add conditional I<OPERATOR> to this object's I<program>.
988              
989             When this I<OPERATOR> should be executed, C<\&conditional> will be called
990             with single param:
991              
992             ( $defer_object )
993              
994             The C<\&conditional> B<MUST> be sync, and return true/false.
995              
996             =item while( \&conditional )
997              
998             =item end_while()
999              
1000             Add loop I<OPERATOR> to this object's I<program>.
1001              
1002             When this I<OPERATOR> should be executed, C<\&conditional> will be called with
1003             single param:
1004              
1005             ( $defer_object )
1006              
1007             The C<\&conditional> B<MUST> be sync, and return true/false.
1008              
1009             =item try()
1010              
1011             =item catch( $regex_or_FINALLY => \&sync_or_async_code, ... )
1012              
1013             Add exception handling to this object's I<program>.
1014              
1015             In general, try/catch/finally behaviour is same as in Java (and probably
1016             many other languages).
1017              
1018             If some I<STATEMENTS> inside try/catch block will C<throw()>, the thrown error
1019             can be intercepted (using matching regexp in C<catch()>) and handled in any
1020             way (blocked - if C<catch()> handler call C<done()>, C<continue()> or C<break()> or
1021             replaced by another exception - if C<catch()> handler call C<throw()>).
1022             If exception match more than one regexp, first successfully matched
1023             regexp's handler will be used. Handler will be executed with params:
1024              
1025             ( $defer_object, $error )
1026              
1027             In addition to exception handlers you can also define FINALLY handler
1028             (by using string C<"FINALLY"> instead of regex). FINALLY handler will be
1029             called in any case (with/without exception) and may handle this in any way
1030             just like any other exception handler in C<catch()>. FINALLY handler will
1031             be executed with different params:
1032              
1033             # with exception
1034             ( $defer_object, $error)
1035             # without exception
1036             ( $defer_object, @optional_results_from_previous_STATEMENT )
1037              
1038             =back
1039              
1040             =head2 FLOW CONTROL in STATEMENTS
1041              
1042             Unless you are nesting child defers, one and only one of these methods B<MUST> be
1043             called at end of each I<STATEMENT>, both sync and async!
1044             In the case of nested defers, see L</"NESTED DEFERS">.
1045              
1046             =over
1047              
1048             =item done( @optional_result )
1049              
1050             Go to continue I<STATEMENT>/I<OPERATOR>. If continue is I<STATEMENT>, it will receive
1051             C<@optional_result> in it parameters.
1052              
1053             =item throw( $error )
1054              
1055             Throw exception. Nearest matching C<catch()> or FINALLY I<STATEMENT> will be
1056             executed and receive C<$error> in it parameter.
1057              
1058             =item continue()
1059              
1060             Move to beginning of nearest C<while()> (or to first I<STATEMENT> if
1061             called outside C<while()>) and continue with continue iteration (if C<while()>'s
1062             C<\&conditional> still returns true).
1063              
1064             =item break()
1065              
1066             Move to first I<STATEMENT>/I<OPERATOR> after nearest C<while()> (or finish this
1067             I<program> if called outside C<while()> - returning to parent's Defer object
1068             if any).
1069              
1070             =back
1071              
1072              
1073             =head1 BUGS AND LIMITATIONS
1074              
1075             No bugs have been reported.
1076              
1077              
1078             =head1 SUPPORT
1079              
1080             Please report any bugs or feature requests through the web interface at
1081             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Async-Defer>.
1082             I will be notified, and then you'll automatically be notified of progress
1083             on your bug as I make changes.
1084              
1085             You can also look for information at:
1086              
1087             =over
1088              
1089             =item * RT: CPAN's request tracker
1090              
1091             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Async-Defer>
1092              
1093             =item * AnnoCPAN: Annotated CPAN documentation
1094              
1095             L<http://annocpan.org/dist/Async-Defer>
1096              
1097             =item * CPAN Ratings
1098              
1099             L<http://cpanratings.perl.org/d/Async-Defer>
1100              
1101             =item * Search CPAN
1102              
1103             L<http://search.cpan.org/dist/Async-Defer/>
1104              
1105             =back
1106              
1107              
1108             =head1 AUTHOR
1109              
1110             Alex Efros C<< <powerman-asdf@ya.ru> >>
1111              
1112              
1113             =head1 CONTRIBUTORS
1114              
1115             Toshio Ito C<< toshioito [at] cpan.org >>
1116              
1117              
1118             =head1 LICENSE AND COPYRIGHT
1119              
1120             Copyright 2011,2012 Alex Efros <powerman-asdf@ya.ru>.
1121              
1122             This program is distributed under the MIT (X11) License:
1123             L<http://www.opensource.org/licenses/mit-license.php>
1124              
1125             Permission is hereby granted, free of charge, to any person
1126             obtaining a copy of this software and associated documentation
1127             files (the "Software"), to deal in the Software without
1128             restriction, including without limitation the rights to use,
1129             copy, modify, merge, publish, distribute, sublicense, and/or sell
1130             copies of the Software, and to permit persons to whom the
1131             Software is furnished to do so, subject to the following
1132             conditions:
1133              
1134             The above copyright notice and this permission notice shall be
1135             included in all copies or substantial portions of the Software.
1136              
1137             THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1138             EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
1139             OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1140             NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1141             HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1142             WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1143             FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1144             OTHER DEALINGS IN THE SOFTWARE.
1145