| 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 |  |  |  |  |  |  |  |