line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Async::Hooks::Ctl; |
2
|
|
|
|
|
|
|
{ |
3
|
|
|
|
|
|
|
$Async::Hooks::Ctl::VERSION = '0.16'; |
4
|
|
|
|
|
|
|
} |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
# ABSTRACT: Hook control object |
7
|
|
|
|
|
|
|
|
8
|
4
|
|
|
4
|
|
49230
|
use strict; |
|
4
|
|
|
|
|
9
|
|
|
4
|
|
|
|
|
144
|
|
9
|
4
|
|
|
4
|
|
21
|
use warnings; |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
1238
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
# $self is a arrayref with three positions: |
12
|
|
|
|
|
|
|
# . first is a arrayref with hooks to call; |
13
|
|
|
|
|
|
|
# . second is a arrayref with the arguments of each hook; |
14
|
|
|
|
|
|
|
# . third is the cleanup sub: always called even when done(). |
15
|
|
|
|
|
|
|
# |
16
|
|
|
|
|
|
|
|
17
|
23
|
|
100
|
23
|
1
|
19926
|
sub new { return bless [undef, $_[1] || [], $_[2] || [], $_[3]], $_[0] } |
|
|
|
100
|
|
|
|
|
18
|
|
|
|
|
|
|
|
19
|
2
|
|
|
2
|
1
|
34
|
sub args { return $_[0][2] } |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# stop() or done() stops the chain |
22
|
|
|
|
|
|
|
sub done { |
23
|
7
|
|
|
7
|
1
|
417
|
my $ctl = $_[0]; |
24
|
|
|
|
|
|
|
|
25
|
7
|
|
|
|
|
12
|
@{$ctl->[1]} = (); |
|
7
|
|
|
|
|
16
|
|
26
|
|
|
|
|
|
|
|
27
|
7
|
|
|
|
|
20
|
return $ctl->_cleanup(1); |
28
|
|
|
|
|
|
|
} |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
*stop = \&done; |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
# decline(), declined() or next() will call the next hook in the chain |
34
|
|
|
|
|
|
|
sub decline { |
35
|
48
|
|
|
48
|
1
|
11504
|
my $ctl = $_[0]; |
36
|
|
|
|
|
|
|
|
37
|
48
|
|
|
|
|
81
|
my $hook = shift @{$ctl->[1]}; |
|
48
|
|
|
|
|
134
|
|
38
|
48
|
100
|
|
|
|
192
|
return $hook->($ctl, $ctl->[2]) if $hook; |
39
|
|
|
|
|
|
|
|
40
|
15
|
|
|
|
|
43
|
return $ctl->_cleanup(0); |
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
*declined = \&decline; |
44
|
|
|
|
|
|
|
*next = \&declined; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
# _cleanup ends the chain processing |
48
|
|
|
|
|
|
|
sub _cleanup { |
49
|
22
|
|
|
22
|
|
36
|
my ($ctl, $is_done) = @_; |
50
|
|
|
|
|
|
|
|
51
|
22
|
100
|
|
|
|
88
|
return unless my $cleanup = $ctl->[3]; |
52
|
11
|
|
100
|
|
|
63
|
return $cleanup->($ctl, $ctl->[2], $is_done || 0); |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
1; # End of Async::Hooks::Ctl |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
__END__ |
59
|
|
|
|
|
|
|
=pod |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=head1 NAME |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
Async::Hooks::Ctl - Hook control object |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=head1 VERSION |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
version 0.16 |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
=head1 SYNOPSIS |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
# inside a callback |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub my_callback { |
74
|
|
|
|
|
|
|
my $ctl = shift; # This is the Async::Hooks::Ctl object |
75
|
|
|
|
|
|
|
my $args = shift; # Arguments for the hook |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
$args = $ctl->args; # Args are also available with the args() method |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
return $ctl->done; # no other callbacks are called |
80
|
|
|
|
|
|
|
# ... or ... |
81
|
|
|
|
|
|
|
return $ctl->decline; # call next callback |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=head1 DESCRIPTION |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
A C<Async::Hooks::Ctl> object controls the sequence of invocation of |
87
|
|
|
|
|
|
|
callbacks. |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
Each callback receives two parameters: a C<Async::Hooks::Ctl> object, |
90
|
|
|
|
|
|
|
and a arrayref with the hook arguments. |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
Each callback must call one of the sequence control methods before |
93
|
|
|
|
|
|
|
returning. Usually you just write: |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
return $ctl->done(); |
96
|
|
|
|
|
|
|
# ... or ... |
97
|
|
|
|
|
|
|
return $ctl->decline(); |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
If you know what you are doing, you can also do this: |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
$ctl->decline(); |
102
|
|
|
|
|
|
|
# do other stuff here |
103
|
|
|
|
|
|
|
return; |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
But there are no guarantees that your code after the control method call |
106
|
|
|
|
|
|
|
will be run at the end of the callback sequence. |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
The important rule is that you must call one and only one of the control |
109
|
|
|
|
|
|
|
methods per callback. |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
The object provides two methods that control the invocation sequence, |
112
|
|
|
|
|
|
|
C<decline()> and C<done()>. The C<done()> method will stop the sequence, |
113
|
|
|
|
|
|
|
and no other callback will be called. The C<decline()> method will call |
114
|
|
|
|
|
|
|
the next callback in the sequence. |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
A cleanup callback can also be defined, and it will be called at the end |
117
|
|
|
|
|
|
|
of all callbacks, or imediatly after C<done()>. This callback receives a |
118
|
|
|
|
|
|
|
third argument, a flag C<$is_done>, that will be true if the chain |
119
|
|
|
|
|
|
|
ended with a call to C<done()> or C<stop()>. |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
The C<decline()> method can also be called as C<declined()> or |
122
|
|
|
|
|
|
|
C<next()>. The C<done()> method can also be called as C<stop()>. |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
=head1 METHODS |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
=over |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
=item CLASS->new($hooks, $args, $cleanup) |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
The C<new()> constructor returns a C<Async::Hooks::Ctl> object. All |
131
|
|
|
|
|
|
|
parameters are optional. |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=over |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
=item * $hooks |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
An arrayref with all the callbacks to call. |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=item * $args |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
An arrayref with all the hook arguments. |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
=item * $cleanup |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
A coderef with the cleanup callback to use. |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=back |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
=item $ctl->args() |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
Returns the hook arguments. |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
=item $ctl->decline() |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
Calls the next callback in the hook sequence. |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
If there are no callbacks remaining and if a cleanup callback was |
158
|
|
|
|
|
|
|
defined, it will be called with the C<$is_done> flag as false. |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=item $ctl->declined() |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
An alias to C<< $ctl->decline() >>. |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=item $ctl->next() |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
An alias to C<< $ctl->decline() >>. |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=item $ctl->done() |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
Stops the callback sequence. No other callbacks in the sequence will |
171
|
|
|
|
|
|
|
be called. |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
If a cleanup callback was defined, it will be called with the |
174
|
|
|
|
|
|
|
C<$is_done> flag as true. |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=item $ctl->stop() |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
An alias to C<< $ctl->done() >>. |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=back |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=head1 AUTHOR |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
Pedro Melo <melo@cpan.org> |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
This software is Copyright (c) 2011 by Pedro Melo. |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
This is free software, licensed under: |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
The Artistic License 2.0 (GPL Compatible) |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
=cut |
195
|
|
|
|
|
|
|
|