File Coverage

blib/lib/Guard.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 11 11 100.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Guard - safe cleanup blocks
4              
5             =head1 SYNOPSIS
6              
7             use Guard;
8            
9             # temporarily chdir to "/etc" directory, but make sure
10             # to go back to "/" no matter how myfun exits:
11             sub myfun {
12             scope_guard { chdir "/" };
13             chdir "/etc";
14            
15             code_that_might_die_or_does_other_fun_stuff;
16             }
17              
18             # create an object that, when the last reference to it is gone,
19             # invokes the given codeblock:
20             my $guard = guard { print "destroyed!\n" };
21             undef $guard; # probably destroyed here
22              
23             =head1 DESCRIPTION
24              
25             This module implements so-called "guards". A guard is something (usually
26             an object) that "guards" a resource, ensuring that it is cleaned up when
27             expected.
28              
29             Specifically, this module supports two different types of guards: guard
30             objects, which execute a given code block when destroyed, and scoped
31             guards, which are tied to the scope exit.
32              
33             =head1 FUNCTIONS
34              
35             This module currently exports the C and C functions by
36             default.
37              
38             =over 4
39              
40             =cut
41              
42             package Guard;
43              
44 4     4   2823 no warnings;
  4         9  
  4         365  
45              
46             BEGIN {
47 4     4   8 $VERSION = '1.022';
48 4         59 @ISA = qw(Exporter);
49 4         9 @EXPORT = qw(guard scope_guard);
50              
51 4         18 require Exporter;
52              
53 4         20 require XSLoader;
54 4         2421 XSLoader::load Guard, $VERSION;
55             }
56              
57             our $DIED = sub { warn "$@" };
58              
59             =item scope_guard BLOCK
60              
61             =item scope_guard ($coderef)
62              
63             Registers a block that is executed when the current scope (block,
64             function, method, eval etc.) is exited.
65              
66             See the EXCEPTIONS section for an explanation of how exceptions
67             (i.e. C) are handled inside guard blocks.
68              
69             The description below sounds a bit complicated, but that's just because
70             C tries to get even corner cases "right": the goal is to
71             provide you with a rock solid clean up tool.
72              
73             The behaviour is similar to this code fragment:
74              
75             eval ... code following scope_guard ...
76             {
77             local $@;
78             eval BLOCK;
79             eval { $Guard::DIED->() } if $@;
80             }
81             die if $@;
82              
83             Except it is much faster, and the whole thing gets executed even when the
84             BLOCK calls C, C, C or escapes via other means.
85              
86             If multiple BLOCKs are registered to the same scope, they will be executed
87             in reverse order. Other scope-related things such as C are managed
88             via the same mechanism, so variables Cised I calling
89             C will be restored when the guard runs.
90              
91             Example: temporarily change the timezone for the current process,
92             ensuring it will be reset when the C scope is exited:
93              
94             use Guard;
95             use POSIX ();
96              
97             if ($need_to_switch_tz) {
98             # make sure we call tzset after $ENV{TZ} has been restored
99             scope_guard { POSIX::tzset };
100              
101             # localise after the scope_guard, so it gets undone in time
102             local $ENV{TZ} = "Europe/London";
103             POSIX::tzset;
104              
105             # do something with the new timezone
106             }
107              
108             =item my $guard = guard BLOCK
109              
110             =item my $guard = guard ($coderef)
111              
112             Behaves the same as C, except that instead of executing
113             the block on scope exit, it returns an object whose lifetime determines
114             when the BLOCK gets executed: when the last reference to the object gets
115             destroyed, the BLOCK gets executed as with C.
116              
117             See the EXCEPTIONS section for an explanation of how exceptions
118             (i.e. C) are handled inside guard blocks.
119              
120             Example: acquire a Coro::Semaphore for a second by registering a
121             timer. The timer callback references the guard used to unlock it
122             again. (Please ignore the fact that C has a C
123             method that does this already):
124              
125             use Guard;
126             use Coro::AnyEvent;
127             use Coro::Semaphore;
128              
129             my $sem = new Coro::Semaphore;
130              
131             sub lock_for_a_second {
132             $sem->down;
133             my $guard = guard { $sem->up };
134              
135             Coro::AnyEvent::sleep 1;
136              
137             # $sem->up gets executed when returning
138             }
139              
140             The advantage of doing this with a guard instead of simply calling C<<
141             $sem->down >> in the callback is that you can opt not to create the timer,
142             or your code can throw an exception before it can create the timer (or
143             the thread gets canceled), or you can create multiple timers or other
144             event watchers and only when the last one gets executed will the lock be
145             unlocked. Using the C, you do not have to worry about catching all
146             the places where you have to unlock the semaphore.
147              
148             =item $guard->cancel
149              
150             Calling this function will "disable" the guard object returned by the
151             C function, i.e. it will free the BLOCK originally passed to
152             Cand will arrange for the BLOCK not to be executed.
153              
154             This can be useful when you use C to create a cleanup handler to be
155             called under fatal conditions and later decide it is no longer needed.
156              
157             =cut
158              
159             1;
160              
161             =back
162              
163             =head1 EXCEPTIONS
164              
165             Guard blocks should not normally throw exceptions (that is, C). After
166             all, they are usually used to clean up after such exceptions. However,
167             if something truly exceptional is happening, a guard block should of
168             course be allowed to die. Also, programming errors are a large source of
169             exceptions, and the programmer certainly wants to know about those.
170              
171             Since in most cases, the block executing when the guard gets executed does
172             not know or does not care about the guard blocks, it makes little sense to
173             let containing code handle the exception.
174              
175             Therefore, whenever a guard block throws an exception, it will be caught
176             by Guard, followed by calling the code reference stored in C<$Guard::DIED>
177             (with C<$@> set to the actual exception), which is similar to how most
178             event loops handle this case.
179              
180             The default for C<$Guard::DIED> is to call C, i.e. the error is
181             printed as a warning and the program continues.
182              
183             The C<$@> variable will be restored to its value before the guard call in
184             all cases, so guards will not disturb C<$@> in any way.
185              
186             The code reference stored in C<$Guard::DIED> should not die (behaviour is
187             not guaranteed, but right now, the exception will simply be ignored).
188              
189             =head1 AUTHOR
190              
191             Marc Lehmann
192             http://home.schmorp.de/
193              
194             =head1 THANKS
195              
196             Thanks to Marco Maisenhelder, who reminded me of the C<$Guard::DIED>
197             solution to the problem of exceptions.
198              
199             =head1 SEE ALSO
200              
201             L and L, which actually implement
202             dynamically scoped guards only, not the lexically scoped guards that their
203             documentation promises, and have a lot higher CPU, memory and typing
204             overhead.
205              
206             L, which has apparently never been finished and can corrupt
207             memory when used.
208              
209             L seems to have a big SEE ALSO section for even more
210             modules like it.
211              
212             =cut
213