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 | code_that_might_die_or_does_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. |
… | |
… | |
78 | the block on scope exit, it returns an object whose lifetime |
83 | the block on scope exit, it returns an object whose lifetime |
79 | determines when the BLOCK gets executed: when the last reference to |
84 | determines when the BLOCK gets executed: when the last reference to |
80 | the object gets destroyed, the BLOCK gets executed as with |
85 | the object gets destroyed, the BLOCK gets executed as with |
81 | "scope_guard". |
86 | "scope_guard". |
82 | |
87 | |
83 | The returned object can be copied as many times as you want. |
|
|
84 | |
|
|
85 | See the EXCEPTIONS section for an explanation of how exceptions |
88 | See the EXCEPTIONS section for an explanation of how exceptions |
86 | (i.e. "die") are handled inside guard blocks. |
89 | (i.e. "die") are handled inside guard blocks. |
87 | |
90 | |
88 | Example: acquire a Coro::Semaphore for a second by registering a |
91 | Example: acquire a Coro::Semaphore for a second by registering a |
89 | timer. The timer callback references the guard used to unlock it |
92 | timer. The timer callback references the guard used to unlock it |
90 | again. (Please ignore the fact that "Coro::Semaphore" has a "guard" |
93 | again. (Please ignore the fact that "Coro::Semaphore" has a "guard" |
91 | method that does this already): |
94 | method that does this already): |
92 | |
95 | |
93 | use Guard; |
96 | use Guard; |
94 | use AnyEvent; |
97 | use Coro::AnyEvent; |
95 | use Coro::Semaphore; |
98 | use Coro::Semaphore; |
96 | |
99 | |
97 | my $sem = new Coro::Semaphore; |
100 | my $sem = new Coro::Semaphore; |
98 | |
101 | |
99 | sub lock_for_a_second { |
102 | sub lock_for_a_second { |
100 | $sem->down; |
103 | $sem->down; |
101 | my $guard = guard { $sem->up }; |
104 | my $guard = guard { $sem->up }; |
102 | |
105 | |
103 | my $timer; |
106 | Coro::AnyEvent::sleep 1; |
104 | $timer = AnyEvent->timer (after => 1, sub { |
107 | |
105 | # do something |
108 | # $sem->up gets executed when returning |
106 | undef $sem; |
|
|
107 | undef $timer; |
|
|
108 | }); |
|
|
109 | } |
109 | } |
110 | |
110 | |
111 | The advantage of doing this with a guard instead of simply calling |
111 | The advantage of doing this with a guard instead of simply calling |
112 | "$sem->down" in the callback is that you can opt not to create the |
112 | "$sem->down" in the callback is that you can opt not to create the |
113 | timer, or your code can throw an exception before it can create the |
113 | timer, or your code can throw an exception before it can create the |
114 | timer, or you can create multiple timers or other event watchers and |
114 | timer (or the thread gets canceled), or you can create multiple |
115 | only when the last one gets executed will the lock be unlocked. |
115 | timers or other event watchers and only when the last one gets |
116 | Using the "guard", you do not have to worry about catching all the |
116 | executed will the lock be unlocked. Using the "guard", you do not |
117 | places where you have to unlock the semaphore. |
117 | have to worry about catching all the places where you have to unlock |
|
|
118 | the semaphore. |
118 | |
119 | |
119 | $guard->cancel |
120 | $guard->cancel |
120 | Calling this function will "disable" the guard object returned by |
121 | Calling this function will "disable" the guard object returned by |
121 | the "guard" function, i.e. it will free the BLOCK originally passed |
122 | the "guard" function, i.e. it will free the BLOCK originally passed |
122 | to "guard "and will arrange for the BLOCK not to be executed. |
123 | to "guard "and will arrange for the BLOCK not to be executed. |
123 | |
124 | |
124 | This can be useful when you use "guard" to create a fatal cleanup |
125 | This can be useful when you use "guard" to create a cleanup handler |
125 | handler and later decide it is no longer needed. |
126 | to be called under fatal conditions and later decide it is no longer |
|
|
127 | needed. |
126 | |
128 | |
127 | EXCEPTIONS |
129 | EXCEPTIONS |
128 | Guard blocks should not normally throw exceptions (that is, "die"). |
130 | Guard blocks should not normally throw exceptions (that is, "die"). |
129 | After all, they are usually used to clean up after such exceptions. |
131 | After all, they are usually used to clean up after such exceptions. |
130 | However, if something truly exceptional is happening, a guard block |
132 | However, if something truly exceptional is happening, a guard block |
131 | should be allowed to die. Also, programming errors are a large source of |
133 | should of course be allowed to die. Also, programming errors are a large |
132 | exceptions, and the programmer certainly wants to know about those. |
134 | source of exceptions, and the programmer certainly wants to know about |
|
|
135 | those. |
133 | |
136 | |
134 | Since in most cases, the block executing when the guard gets executed |
137 | 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 |
138 | does not know or does not care about the guard blocks, it makes little |
136 | sense to let containing code handle the exception. |
139 | sense to let containing code handle the exception. |
137 | |
140 | |
138 | Therefore, whenever a guard block throws an exception, it will be |
141 | Therefore, whenever a guard block throws an exception, it will be caught |
139 | caught, followed by calling the code reference stored in $Guard::DIED |
142 | by Guard, followed by calling the code reference stored in $Guard::DIED |
140 | (with $@ set to the actual exception), which is similar to how most |
143 | (with $@ set to the actual exception), which is similar to how most |
141 | event loops handle this case. |
144 | event loops handle this case. |
142 | |
145 | |
143 | The default for $Guard::DIED is to call "warn "$@"". |
146 | The default for $Guard::DIED is to call "warn "$@"", i.e. the error is |
|
|
147 | printed as a warning and the program continues. |
144 | |
148 | |
145 | The $@ variable will be restored to its value before the guard call in |
149 | The $@ variable will be restored to its value before the guard call in |
146 | all cases, so guards will not disturb $@ in any way. |
150 | all cases, so guards will not disturb $@ in any way. |
147 | |
151 | |
148 | The code reference stored in $Guard::DIED should not die (behaviour is |
152 | The code reference stored in $Guard::DIED should not die (behaviour is |
… | |
… | |
155 | THANKS |
159 | THANKS |
156 | Thanks to Marco Maisenhelder, who reminded me of the $Guard::DIED |
160 | Thanks to Marco Maisenhelder, who reminded me of the $Guard::DIED |
157 | solution to the problem of exceptions. |
161 | solution to the problem of exceptions. |
158 | |
162 | |
159 | SEE ALSO |
163 | SEE ALSO |
160 | Scope::Guard and Sub::ScopeFinalizer, which actually implement dynamic, |
164 | Scope::Guard and Sub::ScopeFinalizer, which actually implement dynamic |
161 | not scoped guards, and have a lot higher CPU, memory and typing |
165 | guards only, not scoped guards, and have a lot higher CPU, memory and |
162 | overhead. |
166 | typing overhead. |
163 | |
167 | |
164 | Hook::Scope, which has apparently never been finished and corrupts |
168 | Hook::Scope, which has apparently never been finished and can corrupt |
165 | memory when used. |
169 | memory when used. |
166 | |
170 | |