File Coverage

blib/lib/AnyEvent/CallbackStack.pm
Criterion Covered Total %
statement 55 56 98.2
branch 6 8 75.0
condition n/a
subroutine 16 17 94.1
pod 8 8 100.0
total 85 89 95.5


line stmt bran cond sub pod time code
1             package AnyEvent::CallbackStack;
2              
3              
4             our $VERSION = '0.12';
5              
6 3     3   35026 use utf8;
  3         25  
  3         31  
7 3     3   76 use feature 'say';
  3         3  
  3         229  
8 3     3   1227 use common::sense;
  3         24  
  3         9  
9 3     3   1351 use Data::Dumper::Simple;
  3         71950  
  3         14  
10              
11 3     3   206130 use AnyEvent;
  3         11723  
  3         102  
12 3     3   15 use constant DEBUG => $ENV{ANYEVENT_CALLBACKSTACK_DEBUG};
  3         3  
  3         1772  
13              
14              
15             =encoding utf8
16              
17             =head1 NAME
18              
19             AnyEvent::CallbackStack - Turning endless nested Event-Based Callbacks into plain Sequential Style. And save your indents.
20              
21             Convert nested callback into easy-to-read-write-and-maintain serial/procedural coding style by using Callback Stack.
22              
23             =head1 SYNOPSIS
24              
25             Use L with the following style.
26              
27             use feature 'say';
28             use AnyEvent::CallbackStack;
29            
30             my $cs = AnyEvent::CallbackStack->new();
31             $cs->start( %foo );
32              
33             $cs->add( sub {
34             do_something;
35             $cs->next( $bar, $yohoo );
36             });
37            
38             $cv = $cs->last;
39             return $cv;
40              
41             # or
42              
43             http_get http://BlueT.org => sub { $cs->start($_[0]) };
44             $cs->add( sub { say $_[0]->recv; $cs->next } );
45             $cs->last->cb(sub {
46             # do something after that
47             # and maybe let me know someone's using my module :3
48             });
49              
50             # or
51              
52             $cs->add( sub { say 'I got the ball'; $cs->next( $_[0]->recv ); } )
53             print 'Your name please?: ';
54             chomp(my $in = );
55             $cs->start($in);
56             $cs->add( sub { say "Lucky you, $_[0]->recv" } );
57              
58             # or
59              
60             my $cs = AE::CS;
61              
62             =head1 METHODS
63              
64             =head2 new
65              
66             No paramater needed.
67              
68             my $cs = new AnyEvent::CallbackStack;
69              
70             =cut
71              
72             sub new {
73 2     2 1 19 my $class = shift;
74            
75 2         4 my @cbq = ();
76 2         48 push @cbq, AE::cv;
77            
78 2         5837 my $self = {
79             cbq => \@cbq,
80             current_step => 0,
81             };
82            
83 2         7 bless ($self, $class);
84 2         3 say 'NEW '.Dumper($self) if DEBUG;
85            
86 2         5 return $self;
87             }
88              
89             =head2 start
90              
91             Start and walk through the Callback Stack from step 0.
92              
93             $cs->start( 'foo' );
94              
95             =cut
96              
97             sub start {
98 2     2 1 62 my $self = shift;
99 2         5 $self->current_step(0);
100            
101 2         2 say 'Start '.Dumper ($self) if DEBUG;
102 2         5 $self->step($self->current_step, @_);
103             }
104              
105             =head2 add
106              
107             Add (append) callback into the Callback Stack.
108              
109             $cs->add( $code_ref );
110              
111             =cut
112              
113             sub add {
114 2     2 1 61 my $self = shift;
115 2         33 $self->cbq(AE::cv);
116            
117 2         3 say 'ADD '.Dumper ($self) if DEBUG;
118            
119 2         5 ($self->cbq)[-2]->cb( shift );
120             }
121              
122             =head2 next
123              
124             Check out from the current step and pass value to the next callback in callback stack.
125              
126             $cs->next( @result );
127              
128             IMPORTANT:
129             Remember that only if you call this method, the next callback in stack will be triggered.
130              
131             =cut
132              
133             sub next {
134 1     1 1 884 my $self = shift;
135 1         4 $self->current_step( $self->current_step +1);
136            
137 1         1 say 'NEXT $self->current_step '.Dumper ($self) if DEBUG;
138            
139 1         2 $self->step($self->current_step, @_);
140             }
141              
142             =head2 last
143              
144             Get the very last L object.
145              
146             Usually it's called when you are writing a module and need to return it to your caller.
147              
148             my $cv = $cs->last;
149             # or
150             return $cs->last;
151            
152              
153             =cut
154              
155             sub last {
156 1     1 1 15 my $self = shift;
157            
158 1         1 say 'LAST '.Dumper ($self) if DEBUG;
159            
160 1         2 return ($self->cbq)[-1];
161             }
162              
163             =head2 step
164              
165             Experimental.
166              
167             Start the callback flow from the specified step.
168              
169             $cs->step( 3, @data );
170              
171             =cut
172              
173             sub step {
174 3     3 1 4 my $self = shift;
175 3 50       16 $_[0] =~ /^\d+?$/ ? $self->current_step(shift) : die 'input is not a number in step()';
176            
177 3         4 say 'STEP '.Dumper ($self) if DEBUG;
178            
179 3         6 ($self->cbq)[$self->current_step]->send( @_ );
180             }
181              
182             =head2 cbq
183              
184             Experimental.
185              
186             Callback Queue Getter/Setter.
187              
188             Don't use this directly unless you really know what you're doing.
189              
190             my @cbq = $cs->cbq;
191             $cs->cbq( AE::cv );
192              
193             =cut
194              
195             sub cbq {
196 8     8 1 15 my $self = shift;
197 8 100       16 push @{$self->{'cbq'}}, @_ if @_;
  2         6  
198 8         8 return @{$self->{'cbq'}};
  8         36  
199             }
200              
201             =head2 current_step
202              
203             Experimental.
204              
205             'Current Step Counter' Getter/Setter.
206              
207             Don't use this directly unless you really know what you're doing.
208              
209             my $curr_step = $cs->current_step;
210             $cs->current_step( 0 );
211              
212             =cut
213              
214             sub current_step {
215 13     13 1 11 my $self = shift;
216 13 100       23 $self->{'current_step'} = $_[0] if $_[0];
217 13         24 return $self->{'current_step'};
218             }
219              
220             =head1 SHORTCUT AE::CS API
221              
222             Inspired by AE.
223             Starting with version 0.05, AnyEvent::CallbackStack officially supports a second, much
224             simpler in name, API that is designed to reduce the typing.
225              
226             There is No Magic like what AE has on reducing calling and memory overhead.
227              
228             See the L manpage for details.
229              
230             my $cs = AE::CS;
231              
232             =cut
233              
234             package AE::CS;
235              
236             our $VERSION = $AnyEvent::CallbackStack::VERSION;
237              
238             sub _reset() {
239 0     0   0 eval q{ # poor man's autoloading {}
  3     3   257  
240             *AE::CS = sub {
241             AnyEvent::CallbackStack->new
242             };
243             };
244 3 50       65 die if $@;
245             }
246 3     3   6 BEGIN { _reset }
247              
248              
249             =head1 AUTHOR
250              
251             BlueT - Matthew Lien - 練喆明, C<< >>
252              
253             =head1 BUGS
254              
255             Please report any bugs or feature requests to C, or through
256             the web interface at L. I will be notified, and then you'll
257             automatically be notified of progress on your bug as I make changes.
258              
259              
260              
261              
262             =head1 SUPPORT
263              
264             You can find documentation for this module with the perldoc command.
265              
266             perldoc AnyEvent::CallbackStack
267              
268              
269             You can also look for information at:
270              
271             =over 4
272              
273             =item * RT: CPAN's request tracker
274              
275             L
276              
277             =item * AnnoCPAN: Annotated CPAN documentation
278              
279             L
280              
281             =item * CPAN Ratings
282              
283             L
284              
285             =item * Search CPAN
286              
287             L
288              
289             =item * Launchpad
290              
291             L
292              
293             =item * GitHub
294              
295             L
296              
297             =back
298              
299              
300             =head1 ACKNOWLEDGEMENTS
301              
302              
303             =head1 LICENSE AND COPYRIGHT
304              
305             Copyright 2012 BlueT - Matthew Lien - 練喆明.
306              
307             This program is free software; you can redistribute it and/or modify it
308             under the terms of either: the GNU General Public License as published
309             by the Free Software Foundation; or the Artistic License.
310              
311             See http://dev.perl.org/licenses/ for more information.
312              
313              
314             =cut
315              
316             1; # End of AnyEvent::CallbackStack