… | |
… | |
83 | the block on scope exit, it returns an object whose lifetime |
83 | the block on scope exit, it returns an object whose lifetime |
84 | determines when the BLOCK gets executed: when the last reference to |
84 | determines when the BLOCK gets executed: when the last reference to |
85 | the object gets destroyed, the BLOCK gets executed as with |
85 | the object gets destroyed, the BLOCK gets executed as with |
86 | "scope_guard". |
86 | "scope_guard". |
87 | |
87 | |
88 | The returned object can be copied as many times as you want. |
|
|
89 | |
|
|
90 | See the EXCEPTIONS section for an explanation of how exceptions |
88 | See the EXCEPTIONS section for an explanation of how exceptions |
91 | (i.e. "die") are handled inside guard blocks. |
89 | (i.e. "die") are handled inside guard blocks. |
92 | |
90 | |
93 | Example: acquire a Coro::Semaphore for a second by registering a |
91 | Example: acquire a Coro::Semaphore for a second by registering a |
94 | timer. The timer callback references the guard used to unlock it |
92 | timer. The timer callback references the guard used to unlock it |
95 | again. (Please ignore the fact that "Coro::Semaphore" has a "guard" |
93 | again. (Please ignore the fact that "Coro::Semaphore" has a "guard" |
96 | method that does this already): |
94 | method that does this already): |
97 | |
95 | |
98 | use Guard; |
96 | use Guard; |
99 | use AnyEvent; |
97 | use Coro::AnyEvent; |
100 | use Coro::Semaphore; |
98 | use Coro::Semaphore; |
101 | |
99 | |
102 | my $sem = new Coro::Semaphore; |
100 | my $sem = new Coro::Semaphore; |
103 | |
101 | |
104 | sub lock_for_a_second { |
102 | sub lock_for_a_second { |
105 | $sem->down; |
103 | $sem->down; |
106 | my $guard = guard { $sem->up }; |
104 | my $guard = guard { $sem->up }; |
107 | |
105 | |
108 | my $timer; |
106 | Coro::AnyEvent::sleep 1; |
109 | $timer = AnyEvent->timer (after => 1, sub { |
107 | |
110 | # do something |
108 | # $sem->up gets executed when returning |
111 | undef $sem; |
|
|
112 | undef $timer; |
|
|
113 | }); |
|
|
114 | } |
109 | } |
115 | |
110 | |
116 | 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 |
117 | "$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 |
118 | 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 |
119 | timer, or you can create multiple timers or other event watchers and |
114 | timer (or the thread gets canceled), or you can create multiple |
120 | 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 |
121 | 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 |
122 | 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. |
123 | |
119 | |
124 | $guard->cancel |
120 | $guard->cancel |
125 | Calling this function will "disable" the guard object returned by |
121 | Calling this function will "disable" the guard object returned by |
126 | 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 |
127 | 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. |
128 | |
124 | |
129 | 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 |
130 | 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. |
131 | |
128 | |
132 | EXCEPTIONS |
129 | EXCEPTIONS |
133 | Guard blocks should not normally throw exceptions (that is, "die"). |
130 | Guard blocks should not normally throw exceptions (that is, "die"). |
134 | 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. |
135 | However, if something truly exceptional is happening, a guard block |
132 | However, if something truly exceptional is happening, a guard block |
136 | 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 |
137 | exceptions, and the programmer certainly wants to know about those. |
134 | source of exceptions, and the programmer certainly wants to know about |
|
|
135 | those. |
138 | |
136 | |
139 | 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 |
140 | 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 |
141 | sense to let containing code handle the exception. |
139 | sense to let containing code handle the exception. |
142 | |
140 | |
143 | Therefore, whenever a guard block throws an exception, it will be |
141 | Therefore, whenever a guard block throws an exception, it will be caught |
144 | caught, followed by calling the code reference stored in $Guard::DIED |
142 | by Guard, followed by calling the code reference stored in $Guard::DIED |
145 | (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 |
146 | event loops handle this case. |
144 | event loops handle this case. |
147 | |
145 | |
148 | 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. |
149 | |
148 | |
150 | 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 |
151 | all cases, so guards will not disturb $@ in any way. |
150 | all cases, so guards will not disturb $@ in any way. |
152 | |
151 | |
153 | 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 |
… | |
… | |
160 | THANKS |
159 | THANKS |
161 | Thanks to Marco Maisenhelder, who reminded me of the $Guard::DIED |
160 | Thanks to Marco Maisenhelder, who reminded me of the $Guard::DIED |
162 | solution to the problem of exceptions. |
161 | solution to the problem of exceptions. |
163 | |
162 | |
164 | SEE ALSO |
163 | SEE ALSO |
165 | Scope::Guard and Sub::ScopeFinalizer, which actually implement dynamic, |
164 | Scope::Guard and Sub::ScopeFinalizer, which actually implement dynamic |
166 | 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 |
167 | overhead. |
166 | typing overhead. |
168 | |
167 | |
169 | Hook::Scope, which has apparently never been finished and corrupts |
168 | Hook::Scope, which has apparently never been finished and can corrupt |
170 | memory when used. |
169 | memory when used. |
171 | |
170 | |