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.22 by root, Sun Jul 26 08:07:11 2009 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines