|
| 1 | +=begin pod |
| 2 | +
|
| 3 | +=TITLE Phasers |
| 4 | +
|
| 5 | +=SUBTITLE Program execution phases and corresponding phaser blocks |
| 6 | +
|
| 7 | +The lifetime (execution timeline) of a program is broken up into phases. A |
| 8 | +I<phaser> is a block of code called during a specific execution phase. |
| 9 | +
|
| 10 | +=head1 Phasers |
| 11 | +
|
| 12 | +A phaser block is just a trait of the closure containing it, and is |
| 13 | +automatically called at the appropriate moment. These auto-called blocks are |
| 14 | +known as I<phasers>, since they generally mark the transition from one phase of |
| 15 | +computing to another. For instance, a C<CHECK> block is called at the end of |
| 16 | +compiling a compilation unit. Other kinds of phasers can be installed as well; |
| 17 | +these are automatically called at various times as appropriate, and some of |
| 18 | +them respond to various control exceptions and exit values. |
| 19 | +
|
| 20 | +Here is a summary: |
| 21 | +
|
| 22 | + BEGIN {...} # * at compile time, ASAP, only ever runs once |
| 23 | + CHECK {...} # * at compile time, ALAP, only ever runs once |
| 24 | + LINK {...} # * at link time, ALAP, only ever runs once |
| 25 | + INIT {...} # * at run time, ASAP, only ever runs once |
| 26 | + END {...} # at run time, ALAP, only ever runs once |
| 27 | +
|
| 28 | + ENTER {...} # * at every block entry time, repeats on loop blocks. |
| 29 | + LEAVE {...} # at every block exit time (even stack unwinds from exceptions) |
| 30 | + KEEP {...} # at every successful block exit, part of LEAVE queue |
| 31 | + UNDO {...} # at every unsuccessful block exit, part of LEAVE queue |
| 32 | +
|
| 33 | + FIRST {...} # * at loop initialization time, before any ENTER |
| 34 | + NEXT {...} # at loop continuation time, before any LEAVE |
| 35 | + LAST {...} # at loop termination time, after any LEAVE |
| 36 | +
|
| 37 | + PRE {...} # assert precondition at every block entry, before ENTER |
| 38 | + POST {...} # assert postcondition at every block exit, after LEAVE |
| 39 | +
|
| 40 | + CATCH {...} # catch exceptions, before LEAVE |
| 41 | + CONTROL {...} # catch control exceptions, before LEAVE |
| 42 | +
|
| 43 | + COMPOSE {...} # when a role is composed into a class |
| 44 | +
|
| 45 | +Phasers marked with a C<*> have a run-time value, and if evaluated earlier than |
| 46 | +their surrounding expression, they simply save their result for use in the |
| 47 | +expression later when the rest of the expression is evaluated: |
| 48 | +
|
| 49 | + my $compiletime = BEGIN { now }; |
| 50 | + our $temphandle = ENTER { maketemp() }; |
| 51 | +
|
| 52 | +As with other statement prefixes, these value-producing constructs may be |
| 53 | +placed in front of either a block or a statement: |
| 54 | +
|
| 55 | + my $compiletime = BEGIN now; |
| 56 | + our $temphandle = ENTER maketemp(); |
| 57 | +
|
| 58 | +Most of these phasers will take either a block or a function reference. The |
| 59 | +statement form can be particularly useful to expose a lexically scoped |
| 60 | +declaration to the surrounding lexical scope without "trapping" it inside a |
| 61 | +block. |
| 62 | +
|
| 63 | +These declare the same variables with the same scope as the preceding example, |
| 64 | +but run the statements as a whole at the indicated time: |
| 65 | +
|
| 66 | + BEGIN my $compiletime = now; |
| 67 | + ENTER our $temphandle = maketemp(); |
| 68 | +
|
| 69 | +(Note, however, that the value of a variable calculated at compile time may not |
| 70 | +persist under run-time cloning of any surrounding closure.) |
| 71 | +
|
| 72 | +
|
| 73 | +Most of the non-value-producing phasers may also be so used: |
| 74 | +
|
| 75 | + END say my $accumulator; |
| 76 | +
|
| 77 | +Note, however, that |
| 78 | +
|
| 79 | + END say my $accumulator = 0; |
| 80 | +
|
| 81 | +sets the variable to 0 at C<END> time, since that is when the "my" declaration |
| 82 | +is actually executed. Only argumentless phasers may use the statement form. |
| 83 | +This means that C<CATCH> and C<CONTROL> always require a block, since they take |
| 84 | +an argument that sets C<$_> to the current topic, so that the innards are able |
| 85 | +to behave as a switch statement. (If bare statements were allowed, the |
| 86 | +temporary binding of C<$_> would leak out past the end of the C<CATCH> or |
| 87 | +C<CONTROL>, with unpredictable and quite possibly dire consequences. Exception |
| 88 | +handlers are supposed to reduce uncertainty, not increase it.) |
| 89 | +
|
| 90 | +Some of these phasers also have corresponding traits that can be set on |
| 91 | +variables. These have the advantage of passing the variable in question into |
| 92 | +the closure as its topic: |
| 93 | +
|
| 94 | + our $h will enter { .rememberit() } will undo { .forgetit() }; |
| 95 | +
|
| 96 | +Only phasers that can occur multiple times within a block are eligible for this |
| 97 | +per-variable form. |
| 98 | +
|
| 99 | +The topic of the block outside a phaser is still available as C<< OUTER::<$_> |
| 100 | +>>. Whether the return value is modifiable may be a policy of the phaser in |
| 101 | +question. In particular, the return value should not be modified within a |
| 102 | +C<POST> phaser, but a C<LEAVE> phaser could be more liberal. |
| 103 | +
|
| 104 | +Any phaser defined in the lexical scope of a method is a closure that closes |
| 105 | +over C<self> as well as normal lexicals. (Or equivalently, an implementation |
| 106 | +may simply turn all such phasers into submethods whose primed invocant is the |
| 107 | +current object.) |
| 108 | +
|
| 109 | +When multiple phasers are scheduled to run at the same moment, the general |
| 110 | +tiebreaking principle is that initializing phasers execute in order declared, |
| 111 | +while finalizing phasers execute in the opposite order, because setup and |
| 112 | +teardown usually want to happen in the opposite order from each other. |
| 113 | +
|
| 114 | +=head2 Execution Order |
| 115 | +
|
| 116 | + Compilation Begins |
| 117 | +
|
| 118 | + BEGIN {...} # at compile time, ASAP, only ever runs once |
| 119 | + CHECK {...} # at compile time, ALAP, only ever runs once |
| 120 | + LINK {...} # at link time, ALAP, only ever runs once |
| 121 | + COMPOSE {...} # when a role is composed into a class |
| 122 | +
|
| 123 | + Execution Begins |
| 124 | +
|
| 125 | + INIT {...} # at run time, ASAP, only ever runs once |
| 126 | +
|
| 127 | + Before block execution begins |
| 128 | +
|
| 129 | + PRE {...} # assert precondition at every block entry, before ENTER |
| 130 | +
|
| 131 | + Loop execution begins |
| 132 | +
|
| 133 | + FIRST {...} # at loop initialization time, before any ENTER |
| 134 | +
|
| 135 | + Block execution begins |
| 136 | +
|
| 137 | + ENTER {...} # at every block entry time, repeats on loop blocks. |
| 138 | +
|
| 139 | + Exception maybe happens |
| 140 | +
|
| 141 | + CATCH {...} # catch exceptions, before LEAVE |
| 142 | + CONTROL {...} # catch control exceptions, before LEAVE |
| 143 | +
|
| 144 | + End of loop, either continuing or finished |
| 145 | +
|
| 146 | + NEXT {...} # at loop continuation time, before any LEAVE |
| 147 | + LAST {...} # at loop termination time, after any LEAVE |
| 148 | +
|
| 149 | + End of block |
| 150 | +
|
| 151 | + LEAVE {...} # at every block exit time (even stack unwinds from exceptions) |
| 152 | + KEEP {...} # at every successful block exit, part of LEAVE queue |
| 153 | + UNDO {...} # at every unsuccessful block exit, part of LEAVE queue |
| 154 | +
|
| 155 | + Post-condition for block |
| 156 | +
|
| 157 | + POST {...} # assert postcondition at every block exit, after LEAVE |
| 158 | +
|
| 159 | + Program terminating |
| 160 | +
|
| 161 | + END {...} # at run time, ALAP, only ever runs once |
| 162 | +
|
| 163 | +=head1 Program Execution Phasers |
| 164 | +
|
| 165 | +=head2 BEGIN |
| 166 | +
|
| 167 | +Runs at compile time, As Soon As Possible, only runs once. |
| 168 | +
|
| 169 | +Can have a return value that is provided even in later phases. |
| 170 | +
|
| 171 | +=head2 CHECK |
| 172 | +
|
| 173 | +Runs at compile time, As Last As Possible, only runs once. |
| 174 | +
|
| 175 | +Can have a return value that is provided even in later phases. |
| 176 | +
|
| 177 | +Code that is generated at run time can still fire off C<CHECK> and C<INIT> |
| 178 | +phasers, though of course those phasers can't do things that would require |
| 179 | +travel back in time. You need a wormhole for that. |
| 180 | +
|
| 181 | +=head2 LINK |
| 182 | +
|
| 183 | +Runs at link time, As Last As Possible, only runs once. |
| 184 | +
|
| 185 | +Can have a return value that is provided even in later phases. |
| 186 | +
|
| 187 | +The compiler is free to ignore C<LINK> phasers compiled at run time since |
| 188 | +they're too late for the application-wide linking decisions. |
| 189 | +
|
| 190 | +=head2 INIT |
| 191 | +
|
| 192 | +Runs after compilation during main execution, As Soon As Possible, only runs |
| 193 | +once. |
| 194 | +
|
| 195 | +Can have a return value that is provided even in later phases. |
| 196 | +
|
| 197 | +When phasers are in different modules, the C<INIT> and C<END> phasers are |
| 198 | +treated as if declared at C<use> time in the using module. (It is erroneous to |
| 199 | +depend on this order if the module is used more than once, however, since the |
| 200 | +phasers are only installed the first time they're noticed.) |
| 201 | +
|
| 202 | +Code that is generated at run time can still fire off C<CHECK> and C<INIT> |
| 203 | +phasers, though of course those phasers can't do things that would require |
| 204 | +travel back in time. You need a wormhole for that. |
| 205 | +
|
| 206 | +An C<INIT> only runs once for all copies of a cloned closure. |
| 207 | +
|
| 208 | +=head2 END |
| 209 | +
|
| 210 | +Runs after compilation during main execution, As Last As Possible, only runs |
| 211 | +once. |
| 212 | +
|
| 213 | +When phasers are in different modules, the C<INIT> and C<END> phasers are |
| 214 | +treated as if declared at C<use> time in the using module. (It is erroneous to |
| 215 | +depend on this order if the module is used more than once, however, since the |
| 216 | +phasers are only installed the first time they're noticed.) |
| 217 | +
|
| 218 | +=head1 Block Phasers |
| 219 | +
|
| 220 | +Execution in the context of a block has it's own phases. |
| 221 | +
|
| 222 | +Block-leaving phasers wait until the call stack is actually unwound to run. |
| 223 | +Unwinding happens only after some exception handler decides to handle the |
| 224 | +exception that way. That is, just because an exception is thrown past a stack |
| 225 | +frame does not mean we have officially left the block yet, since the exception |
| 226 | +might be resumable. In any case, exception handlers are specified to run within |
| 227 | +the dynamic scope of the failing code, whether or not the exception is |
| 228 | +resumable. The stack is unwound and the phasers are called only if an exception |
| 229 | +is not resumed. |
| 230 | +
|
| 231 | +These can occur multiple times within the block. So they aren't really traits, |
| 232 | +exactly--they add themselves onto a list stored in the actual trait. So if you |
| 233 | +examine the C<ENTER> trait of a block, you'll find that it's really a list of |
| 234 | +phasers rather than a single phaser. |
| 235 | +
|
| 236 | +All of these phaser blocks can see any previously declared lexical variables, |
| 237 | +even if those variables have not been elaborated yet when the closure is |
| 238 | +invoked (in which case the variables evaluate to an undefined value.) |
| 239 | +
|
| 240 | +=head2 ENTER |
| 241 | +
|
| 242 | +Runs at every block entry time, repeats on loop blocks. |
| 243 | +
|
| 244 | +Can have a return value that is provided even in later phases. |
| 245 | +
|
| 246 | +An exception thrown from an C<ENTER> phaser will abort the C<ENTER> queue, but |
| 247 | +one thrown from a C<LEAVE> phaser will not. |
| 248 | +
|
| 249 | +=head2 LEAVE |
| 250 | +
|
| 251 | +Runs at every block exit time (even stack unwinds from exceptions). |
| 252 | +
|
| 253 | +So C<LEAVE> phasers for a given block are necessarily evaluated after any |
| 254 | +C<CATCH> and C<CONTROL> phasers. This includes the C<LEAVE> variants, C<KEEP> |
| 255 | +and C<UNDO>. C<POST> phasers are evaluated after everything else, to guarantee |
| 256 | +that even C<LEAVE> phasers can't violate postconditions. |
| 257 | +
|
| 258 | +An exception thrown from an C<ENTER> phaser will abort the C<ENTER> queue, but |
| 259 | +one thrown from a C<LEAVE> phaser will not. |
| 260 | +
|
| 261 | +If a C<POST> fails or any kind of C<LEAVE> block throws an exception while the |
| 262 | +stack is unwinding, the unwinding continues and collects exceptions to be |
| 263 | +handled. When the unwinding is completed all new exceptions are thrown from |
| 264 | +that point. |
| 265 | +
|
| 266 | +=head2 KEEP |
| 267 | +
|
| 268 | +Runs at every successful block exit, as part of the LEAVE queue (shares the |
| 269 | +same order of execution). |
| 270 | +
|
| 271 | +For phasers such as C<KEEP> and C<POST> that are run when exiting a scope |
| 272 | +normally, the return value (if any) from that scope is available as the current |
| 273 | +topic within the phaser. |
| 274 | +
|
| 275 | +=head2 UNDO |
| 276 | +
|
| 277 | +Runs at every unsuccessful block exit, as part of the LEAVE queue (shares the |
| 278 | +same order of execution). |
| 279 | +
|
| 280 | +=head2 PRE |
| 281 | +
|
| 282 | +Asserts a precondition at every block entry. Runs before the ENTER phase. |
| 283 | +
|
| 284 | +C<PRE> phasers fire off before any C<ENTER> or C<FIRST>. |
| 285 | +
|
| 286 | +The exceptions thrown by failing C<PRE> and C<POST> phasers cannot be caught by |
| 287 | +a C<CATCH> in the same block, which implies that C<POST> phaser are not run if |
| 288 | +a C<PRE> phaser fails. |
| 289 | +
|
| 290 | +=head2 POST |
| 291 | +
|
| 292 | +Asserts a postcondition at every block entry. Runs after the LEAVE phase. |
| 293 | +
|
| 294 | +For phasers such as C<KEEP> and C<POST> that are run when exiting a scope |
| 295 | +normally, the return value (if any) from that scope is available as the current |
| 296 | +topic within the phaser. |
| 297 | +
|
| 298 | +The C<POST> block can be defined in one of two ways. Either the corresponding |
| 299 | +C<POST> is defined as a separate phaser, in which case C<PRE> and C<POST> share |
| 300 | +no lexical scope. Alternately, any C<PRE> phaser may define its corresponding |
| 301 | +C<POST> as an embedded phaser block that closes over the lexical scope of the |
| 302 | +C<PRE>. |
| 303 | +
|
| 304 | +If a C<POST> fails or any kind of C<LEAVE> block throws an exception while the |
| 305 | +stack is unwinding, the unwinding continues and collects exceptions to be |
| 306 | +handled. When the unwinding is completed all new exceptions are thrown from |
| 307 | +that point. |
| 308 | +
|
| 309 | +The exceptions thrown by failing C<PRE> and C<POST> phasers cannot be caught by |
| 310 | +a C<CATCH> in the same block, which implies that C<POST> phaser are not run if |
| 311 | +a C<PRE> phaser fails. |
| 312 | +
|
| 313 | +=head1 Loop Phasers |
| 314 | +
|
| 315 | +C<FIRST>, C<NEXT>, and C<LAST> are meaningful only within the lexical scope of |
| 316 | +a loop, and may occur only at the top level of such a loop block. |
| 317 | +
|
| 318 | +=head2 FIRST |
| 319 | +
|
| 320 | +Runs at loop initialization, before ENTER. |
| 321 | +
|
| 322 | +Can have a return value that is provided even in later phases. |
| 323 | +
|
| 324 | +=head2 NEXT |
| 325 | +
|
| 326 | +Runs when loop is continued (either through C<next> or because you got to the |
| 327 | +bottom of the loop and are looping back around), before LEAVE. |
| 328 | +
|
| 329 | +A C<NEXT> executes only if the end of the loop block is reached normally, or an |
| 330 | +explicit C<next> is executed. In distinction to C<LEAVE> phasers, a C<NEXT> |
| 331 | +phaser is not executed if the loop block is exited via any exception other than |
| 332 | +the control exception thrown by C<next>. In particular, a C<last> bypasses |
| 333 | +evaluation of C<NEXT> phasers. |
| 334 | +
|
| 335 | +=head2 LAST |
| 336 | +
|
| 337 | +Runs when loop is aborted (either through C<last>, or C<return>, or because you |
| 338 | +got to the bottom of the loop and are done), after LEAVE. |
| 339 | +
|
| 340 | +=head1 Exception Handling Phasers |
| 341 | +
|
| 342 | +=head2 CATCH |
| 343 | +
|
| 344 | +Runs when an exception is raised by the current block, before the LEAVE phase. |
| 345 | +
|
| 346 | +=head2 CONTROL |
| 347 | +
|
| 348 | +Runs when a control exception is raised by the current block, before the LEAVE |
| 349 | +phase. |
| 350 | +
|
| 351 | +=head1 Object Phasers |
| 352 | +
|
| 353 | +=head2 COMPOSE |
| 354 | +
|
| 355 | +Runs when a role is composed into a class. |
| 356 | +
|
| 357 | +=end pod |
0 commit comments