ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Guard/Guard.pm
(Generate patch)

Comparing Guard/Guard.pm (file contents):
Revision 1.21 by root, Sun Jul 19 05:44:10 2009 UTC vs.
Revision 1.23 by root, Fri Mar 12 17:25:58 2010 UTC

56 56
57our $DIED = sub { warn "$@" }; 57our $DIED = sub { warn "$@" };
58 58
59=item scope_guard BLOCK 59=item scope_guard BLOCK
60 60
61=item scope_guard ($coderef)
62
61Registers a block that is executed when the current scope (block, 63Registers a block that is executed when the current scope (block,
62function, method, eval etc.) is exited. 64function, method, eval etc.) is exited.
63 65
64See the EXCEPTIONS section for an explanation of how exceptions 66See the EXCEPTIONS section for an explanation of how exceptions
65(i.e. C<die>) are handled inside guard blocks. 67(i.e. C<die>) are handled inside guard blocks.
103 # do something with the new timezone 105 # do something with the new timezone
104 } 106 }
105 107
106=item my $guard = guard BLOCK 108=item my $guard = guard BLOCK
107 109
110=item my $guard = guard ($coderef)
111
108Behaves the same as C<scope_guard>, except that instead of executing 112Behaves the same as C<scope_guard>, except that instead of executing
109the block on scope exit, it returns an object whose lifetime determines 113the block on scope exit, it returns an object whose lifetime determines
110when the BLOCK gets executed: when the last reference to the object gets 114when the BLOCK gets executed: when the last reference to the object gets
111destroyed, the BLOCK gets executed as with C<scope_guard>. 115destroyed, the BLOCK gets executed as with C<scope_guard>.
112 116
113The returned object can be copied as many times as you want.
114
115See the EXCEPTIONS section for an explanation of how exceptions 117See the EXCEPTIONS section for an explanation of how exceptions
116(i.e. C<die>) are handled inside guard blocks. 118(i.e. C<die>) are handled inside guard blocks.
117 119
118Example: acquire a Coro::Semaphore for a second by registering a 120Example: acquire a Coro::Semaphore for a second by registering a
119timer. The timer callback references the guard used to unlock it 121timer. The timer callback references the guard used to unlock it
120again. (Please ignore the fact that C<Coro::Semaphore> has a C<guard> 122again. (Please ignore the fact that C<Coro::Semaphore> has a C<guard>
121method that does this already): 123method that does this already):
122 124
123 use Guard; 125 use Guard;
124 use AnyEvent; 126 use Coro::AnyEvent;
125 use Coro::Semaphore; 127 use Coro::Semaphore;
126 128
127 my $sem = new Coro::Semaphore; 129 my $sem = new Coro::Semaphore;
128 130
129 sub lock_for_a_second { 131 sub lock_for_a_second {
130 $sem->down; 132 $sem->down;
131 my $guard = guard { $sem->up }; 133 my $guard = guard { $sem->up };
132 134
133 my $timer; 135 Coro::AnyEvent::sleep 1;
134 $timer = AnyEvent->timer (after => 1, sub { 136
135 # do something 137 # $sem->up gets executed when returning
136 undef $sem;
137 undef $timer;
138 });
139 } 138 }
140 139
141The advantage of doing this with a guard instead of simply calling C<< 140The advantage of doing this with a guard instead of simply calling C<<
142$sem->down >> in the callback is that you can opt not to create the timer, 141$sem->down >> in the callback is that you can opt not to create the timer,
143or your code can throw an exception before it can create the timer, or you 142or your code can throw an exception before it can create the timer (or
144can create multiple timers or other event watchers and only when the last 143the thread gets canceled), or you can create multiple timers or other
145one gets executed will the lock be unlocked. Using the C<guard>, you do 144event watchers and only when the last one gets executed will the lock be
146not have to worry about catching all the places where you have to unlock 145unlocked. Using the C<guard>, you do not have to worry about catching all
147the semaphore. 146the places where you have to unlock the semaphore.
148 147
149=item $guard->cancel 148=item $guard->cancel
150 149
151Calling this function will "disable" the guard object returned by the 150Calling this function will "disable" the guard object returned by the
152C<guard> function, i.e. it will free the BLOCK originally passed to 151C<guard> function, i.e. it will free the BLOCK originally passed to
153C<guard >and will arrange for the BLOCK not to be executed. 152C<guard >and will arrange for the BLOCK not to be executed.
154 153
155This can be useful when you use C<guard> to create a fatal cleanup handler 154This can be useful when you use C<guard> to create a cleanup handler to be
156and later decide it is no longer needed. 155called under fatal conditions and later decide it is no longer needed.
157 156
158=cut 157=cut
159 158
1601; 1591;
161 160
162=back 161=back
163 162
164=head1 EXCEPTIONS 163=head1 EXCEPTIONS
165 164
166Guard blocks should not normally throw exceptions (that is, C<die>). After 165Guard blocks should not normally throw exceptions (that is, C<die>). After
167all, they are usually used to clean up after such exceptions. However, if 166all, they are usually used to clean up after such exceptions. However,
168something truly exceptional is happening, a guard block should be allowed 167if something truly exceptional is happening, a guard block should of
169to die. Also, programming errors are a large source of exceptions, and the 168course be allowed to die. Also, programming errors are a large source of
170programmer certainly wants to know about those. 169exceptions, and the programmer certainly wants to know about those.
171 170
172Since in most cases, the block executing when the guard gets executed does 171Since in most cases, the block executing when the guard gets executed does
173not know or does not care about the guard blocks, it makes little sense to 172not know or does not care about the guard blocks, it makes little sense to
174let containing code handle the exception. 173let containing code handle the exception.
175 174
176Therefore, whenever a guard block throws an exception, it will be caught, 175Therefore, whenever a guard block throws an exception, it will be caught
177followed by calling the code reference stored in C<$Guard::DIED> (with 176by Guard, followed by calling the code reference stored in C<$Guard::DIED>
178C<$@> set to the actual exception), which is similar to how most event 177(with C<$@> set to the actual exception), which is similar to how most
179loops handle this case. 178event loops handle this case.
180 179
181The default for C<$Guard::DIED> is to call C<warn "$@">. 180The default for C<$Guard::DIED> is to call C<warn "$@">, i.e. the error is
181printed as a warning and the program continues.
182 182
183The C<$@> variable will be restored to its value before the guard call in 183The C<$@> variable will be restored to its value before the guard call in
184all cases, so guards will not disturb C<$@> in any way. 184all cases, so guards will not disturb C<$@> in any way.
185 185
186The code reference stored in C<$Guard::DIED> should not die (behaviour is 186The code reference stored in C<$Guard::DIED> should not die (behaviour is
197solution to the problem of exceptions. 197solution to the problem of exceptions.
198 198
199=head1 SEE ALSO 199=head1 SEE ALSO
200 200
201L<Scope::Guard> and L<Sub::ScopeFinalizer>, which actually implement 201L<Scope::Guard> and L<Sub::ScopeFinalizer>, which actually implement
202dynamic, not scoped guards, and have a lot higher CPU, memory and typing 202dynamic guards only, not scoped guards, and have a lot higher CPU, memory
203overhead. 203and typing overhead.
204 204
205L<Hook::Scope>, which has apparently never been finished and corrupts 205L<Hook::Scope>, which has apparently never been finished and can corrupt
206memory when used. 206memory when used.
207 207
208=cut 208=cut
209 209

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines