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.26 by root, Tue Mar 21 11:39:27 2017 UTC

42package Guard; 42package Guard;
43 43
44no warnings; 44no warnings;
45 45
46BEGIN { 46BEGIN {
47 $VERSION = '1.021'; 47 $VERSION = 1.023;
48 @ISA = qw(Exporter); 48 @ISA = qw(Exporter);
49 @EXPORT = qw(guard scope_guard); 49 @EXPORT = qw(guard scope_guard);
50 50
51 require Exporter; 51 require Exporter;
52 52
55} 55}
56 56
57our $DIED = sub { warn "$@" }; 57our $DIED = sub { warn "$@" };
58 58
59=item scope_guard BLOCK 59=item scope_guard BLOCK
60
61=item scope_guard ($coderef)
60 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
82BLOCK calls C<exit>, C<goto>, C<last> or escapes via other means. 84BLOCK calls C<exit>, C<goto>, C<last> or escapes via other means.
83 85
84If multiple BLOCKs are registered to the same scope, they will be executed 86If multiple BLOCKs are registered to the same scope, they will be executed
85in reverse order. Other scope-related things such as C<local> are managed 87in reverse order. Other scope-related things such as C<local> are managed
86via the same mechanism, so variables C<local>ised I<after> calling 88via the same mechanism, so variables C<local>ised I<after> calling
87C<scope_guard> will be restored when the guard runs. 89C<scope_guard> will be restored I<before> the guard runs.
88 90
89Example: temporarily change the timezone for the current process, 91Example: temporarily change the timezone for the current process,
90ensuring it will be reset when the C<if> scope is exited: 92ensuring it will be reset when the C<if> scope is exited:
91 93
92 use Guard; 94 use Guard;
102 104
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
109
110=item my $guard = guard ($coderef)
107 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
202dynamically scoped guards only, not the lexically scoped guards that their
202dynamic, not scoped guards, and have a lot higher CPU, memory and typing 203documentation promises, and have a lot higher CPU, memory and typing
203overhead. 204overhead.
204 205
205L<Hook::Scope>, which has apparently never been finished and corrupts 206L<Hook::Scope>, which has apparently never been finished and can corrupt
206memory when used. 207memory when used.
207 208
209L<Scope::Guard> seems to have a big SEE ALSO section for even more
210modules like it.
211
208=cut 212=cut
209 213

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines