1 | NAME |
1 | NAME |
2 | Guard - safe cleanup blocks |
2 | Guard - safe cleanup blocks |
3 | |
3 | |
4 | SYNOPSIS |
4 | SYNOPSIS |
5 | use Guard; |
5 | use Guard; |
6 | |
6 | |
7 | # temporarily chdir to "/etc" directory, but make sure |
7 | # temporarily chdir to "/etc" directory, but make sure |
8 | # to go back to "/" no matter how myfun exits: |
8 | # to go back to "/" no matter how myfun exits: |
9 | sub myfun { |
9 | sub myfun { |
10 | scope_guard { chdir "/" }; |
10 | scope_guard { chdir "/" }; |
11 | chdir "/etc"; |
11 | chdir "/etc"; |
12 | |
12 | |
13 | call_function_that_might_die_or_other_fun_stuff; |
13 | code_that_might_die_or_does_other_fun_stuff; |
14 | } |
14 | } |
|
|
15 | |
|
|
16 | # create an object that, when the last reference to it is gone, |
|
|
17 | # invokes the given codeblock: |
|
|
18 | my $guard = guard { print "destroyed!\n" }; |
|
|
19 | undef $guard; # probably destroyed here |
15 | |
20 | |
16 | DESCRIPTION |
21 | DESCRIPTION |
17 | This module implements so-called "guards". A guard is something (usually |
22 | This module implements so-called "guards". A guard is something (usually |
18 | an object) that "guards" a resource, ensuring that it is cleaned up when |
23 | an object) that "guards" a resource, ensuring that it is cleaned up when |
19 | expected. |
24 | expected. |
… | |
… | |
129 | After all, they are usually used to clean up after such exceptions. |
134 | After all, they are usually used to clean up after such exceptions. |
130 | However, if something truly exceptional is happening, a guard block |
135 | However, if something truly exceptional is happening, a guard block |
131 | should be allowed to die. Also, programming errors are a large source of |
136 | should be allowed to die. Also, programming errors are a large source of |
132 | exceptions, and the programmer certainly wants to know about those. |
137 | exceptions, and the programmer certainly wants to know about those. |
133 | |
138 | |
134 | Since in most cases, the block executing when the guard gets executes |
139 | Since in most cases, the block executing when the guard gets executed |
135 | does not know or does not care about the guard blocks, it makes little |
140 | does not know or does not care about the guard blocks, it makes little |
136 | sense to let containing code handle the exception. |
141 | sense to let containing code handle the exception. |
137 | |
142 | |
138 | Therefore, whenever a guard block throws an exception, it will be |
143 | Therefore, whenever a guard block throws an exception, it will be |
139 | caught, and this module will call the code reference stored in |
144 | caught, followed by calling the code reference stored in $Guard::DIED |
140 | $Guard::DIED (with $@ set to the actual exception), which is similar to |
145 | (with $@ set to the actual exception), which is similar to how most |
141 | how most event loops handle this case. |
146 | event loops handle this case. |
142 | |
147 | |
143 | The default for $Guard::DIED is to call "warn "$@"". |
148 | The default for $Guard::DIED is to call "warn "$@"". |
144 | |
149 | |
145 | The $@ variable will be restored to its value before the guard call in |
150 | The $@ variable will be restored to its value before the guard call in |
146 | all cases, so guards will not disturb $@ in any way. |
151 | all cases, so guards will not disturb $@ in any way. |
… | |
… | |
154 | |
159 | |
155 | THANKS |
160 | THANKS |
156 | Thanks to Marco Maisenhelder, who reminded me of the $Guard::DIED |
161 | Thanks to Marco Maisenhelder, who reminded me of the $Guard::DIED |
157 | solution to the problem of exceptions. |
162 | solution to the problem of exceptions. |
158 | |
163 | |
|
|
164 | SEE ALSO |
|
|
165 | Scope::Guard and Sub::ScopeFinalizer, which actually implement dynamic, |
|
|
166 | not scoped guards, and have a lot higher CPU, memory and typing |
|
|
167 | overhead. |
|
|
168 | |
|
|
169 | Hook::Scope, which has apparently never been finished and corrupts |
|
|
170 | memory when used. |
|
|
171 | |