|
| 1 | +=begin pod |
| 2 | +
|
| 3 | +=TITLE Phasers |
| 4 | +
|
| 5 | +=SUBTITLE Execution phases |
| 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 | +Constructs marked with a C<*> have a run-time value, and if evaluated |
| 46 | +earlier than their surrounding expression, they simply save their result for |
| 47 | +use in the 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 | +Hence these declare the same variables with the same scope as the preceding |
| 64 | +example, 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 |
| 70 | +not persist under run-time cloning of any surrounding closure.) |
| 71 | +
|
| 72 | +Most of the non-value-producing phasers may also be so used: |
| 73 | +
|
| 74 | + END say my $accumulator; |
| 75 | +
|
| 76 | +Note, however, that |
| 77 | +
|
| 78 | + END say my $accumulator = 0; |
| 79 | +
|
| 80 | +sets the variable to 0 at C<END> time, since that is when the "my" |
| 81 | +declaration is actually executed. Only argumentless phasers may use the |
| 82 | +statement form. This means that C<CATCH> and C<CONTROL> always require a |
| 83 | +block, since they take an argument that sets C<$_> to the current topic, so |
| 84 | +that the innards are able to behave as a switch statement. (If bare |
| 85 | +statements were allowed, the temporary binding of C<$_> would leak out past |
| 86 | +the end of the C<CATCH> or C<CONTROL>, with unpredictable and quite possibly |
| 87 | +dire consequences. Exception handlers are supposed to reduce uncertainty, |
| 88 | +not increase it.) |
| 89 | +
|
| 90 | +Code that is generated at run time can still fire off C<CHECK> and C<INIT> |
| 91 | +phasers, though of course those phasers can't do things that would require |
| 92 | +travel back in time. You need a wormhole for that. |
| 93 | +
|
| 94 | +The compiler is free to ignore C<LINK> phasers compiled at run time since |
| 95 | +they're too late for the application-wide linking decisions. |
| 96 | +
|
| 97 | +Some of these phasers also have corresponding traits that can be set on |
| 98 | +variables. These have the advantage of passing the variable in question |
| 99 | +into the closure as its topic: |
| 100 | +
|
| 101 | + our $h will enter { .rememberit() } will undo { .forgetit() }; |
| 102 | +
|
| 103 | +Only phasers that can occur multiple times within a block are eligible for |
| 104 | +this per-variable form. |
| 105 | +
|
| 106 | +Apart from C<CATCH> and C<CONTROL>, which can only occur once, most of these |
| 107 | +can occur multiple times within the block. So they aren't really traits, |
| 108 | +exactly--they add themselves onto a list stored in the actual trait. So if |
| 109 | +you examine the C<ENTER> trait of a block, you'll find that it's really a |
| 110 | +list of phasers rather than a single phaser. |
| 111 | +
|
| 112 | +When multiple phasers are scheduled to run at the same moment, the general |
| 113 | +tiebreaking principle is that initializing phasers execute in order |
| 114 | +declared, while finalizing phasers execute in the opposite order, because |
| 115 | +setup and teardown usually want to happen in the opposite order from each |
| 116 | +other. When phasers are in different modules, the C<INIT> and C<END> |
| 117 | +phasers are treated as if declared at C<use> time in the using module. (It |
| 118 | +is erroneous to depend on this order if the module is used more than once, |
| 119 | +however, since the phasers are only installed the first time they're |
| 120 | +noticed.) |
| 121 | +
|
| 122 | +The semantics of C<INIT> and C<once> are not equivalent to each other in the |
| 123 | +case of cloned closures. An C<INIT> only runs once for all copies of a |
| 124 | +cloned closure. A C<once> runs separately for each clone, so separate |
| 125 | +clones can keep separate state variables: |
| 126 | +
|
| 127 | + our $i = 0; |
| 128 | + ... |
| 129 | + $func = once { state $x { $x = $i++ }; dostuff($i) }; |
| 130 | +
|
| 131 | +But C<state> automatically applies "once" semantics to any initializer, so |
| 132 | +this also works: |
| 133 | +
|
| 134 | + $func = { state $x = $i++; dostuff($i) } |
| 135 | +
|
| 136 | +Each subsequent clone gets an initial state that is one higher than the |
| 137 | +previous, and each clone maintains its own state of C<$x>, because that's |
| 138 | +what C<state> variables do. |
| 139 | +
|
| 140 | +Even in the absence of closure cloning, C<INIT> runs before the mainline |
| 141 | +code, while C<once> puts off the initialization till the last possible |
| 142 | +moment, then runs exactly once, and caches its value for all subsequent |
| 143 | +calls (assuming it wasn't called in sink context, in which case the C<once> |
| 144 | +is evaluated once only for its side effects). In particular, this means |
| 145 | +that C<once> can make use of any parameters passed in on the first call, |
| 146 | +whereas C<INIT> cannot. |
| 147 | +
|
| 148 | +All of these phaser blocks can see any previously declared lexical |
| 149 | +variables, even if those variables have not been elaborated yet when the |
| 150 | +closure is invoked (in which case the variables evaluate to an undefined |
| 151 | +value.) |
| 152 | +
|
| 153 | +Note: Apocalypse 4 confused the notions of C<PRE>/C<POST> with |
| 154 | +C<ENTER>/C<LEAVE>. These are now separate notions. C<ENTER> and C<LEAVE> |
| 155 | +are used only for their side effects. C<PRE> and C<POST> return boolean |
| 156 | +values which, if false, trigger a runtime exception. C<KEEP> and C<UNDO> |
| 157 | +are just variants of C<LEAVE>, and for execution order are treated as part |
| 158 | +of the queue of C<LEAVE> phasers. |
| 159 | +
|
| 160 | +It is conjectured that C<PRE> and C<POST> submethods in a class could be |
| 161 | +made to run as if they were phasers in any public method of the class. This |
| 162 | +feature is awaiting further exploration by means of a C<ClassHOW> extension. |
| 163 | +
|
| 164 | +C<FIRST>, C<NEXT>, and C<LAST> are meaningful only within the lexical scope |
| 165 | +of a loop, and may occur only at the top level of such a loop block. A |
| 166 | +C<NEXT> executes only if the end of the loop block is reached normally, or |
| 167 | +an explicit C<next> is executed. In distinction to C<LEAVE> phasers, a |
| 168 | +C<NEXT> phaser is not executed if the loop block is exited via any exception |
| 169 | +other than the control exception thrown by C<next>. In particular, a |
| 170 | +C<last> bypasses evaluation of C<NEXT> phasers. |
| 171 | +
|
| 172 | +[Note: the name C<FIRST> used to be associated with C<state> declarations. |
| 173 | +Now it is associated only with loops. See the C<once> above for C<state> |
| 174 | +semantics.] |
| 175 | +
|
| 176 | +Except for C<CATCH> and C<CONTROL> phasers, which run while an exception is |
| 177 | +looking for a place to handle it, all block-leaving phasers wait until the |
| 178 | +call stack is actually unwound to run. Unwinding happens only after some |
| 179 | +exception handler decides to handle the exception that way. That is, just |
| 180 | +because an exception is thrown past a stack frame does not mean we have |
| 181 | +officially left the block yet, since the exception might be resumable. In |
| 182 | +any case, exception handlers are specified to run within the dynamic scope |
| 183 | +of the failing code, whether or not the exception is resumable. The stack |
| 184 | +is unwound and the phasers are called only if an exception is not resumed. |
| 185 | +
|
| 186 | +So C<LEAVE> phasers for a given block are necessarily evaluated after any |
| 187 | +C<CATCH> and C<CONTROL> phasers. This includes the C<LEAVE> variants, |
| 188 | +C<KEEP> and C<UNDO>. C<POST> phasers are evaluated after everything else, |
| 189 | +to guarantee that even C<LEAVE> phasers can't violate postconditions. |
| 190 | +Likewise C<PRE> phasers fire off before any C<ENTER> or C<FIRST> (though not |
| 191 | +before C<BEGIN>, C<CHECK>, C<LINK>, or C<INIT>, since those are done at |
| 192 | +compile or process initialization time). |
| 193 | +
|
| 194 | +The C<POST> block can be defined in one of two ways. Either the |
| 195 | +corresponding C<POST> is defined as a separate phaser, in which case C<PRE> |
| 196 | +and C<POST> share no lexical scope. Alternately, any C<PRE> phaser may |
| 197 | +define its corresponding C<POST> as an embedded phaser block that closes |
| 198 | +over the lexical scope of the C<PRE>. |
| 199 | +
|
| 200 | +If exit phasers are running as a result of a stack unwind initiated by an |
| 201 | +exception, this information needs to be made available. In any case, the |
| 202 | +information as to whether the block is being exited successfully or |
| 203 | +unsuccessfully needs to be available to decide whether to run C<KEEP> or |
| 204 | +C<UNDO> blocks (also see L</"Definition of Success">). How this information |
| 205 | +is made available is implementation dependent. |
| 206 | +
|
| 207 | +An exception thrown from an C<ENTER> phaser will abort the C<ENTER> queue, |
| 208 | +but one thrown from a C<LEAVE> phaser will not. The exceptions thrown by |
| 209 | +failing C<PRE> and C<POST> phasers cannot be caught by a C<CATCH> in the |
| 210 | +same block, which implies that C<POST> phaser are not run if a C<PRE> phaser |
| 211 | +fails. |
| 212 | +
|
| 213 | +If a C<POST> fails or any kind of C<LEAVE> block throws an exception while |
| 214 | +the stack is unwinding, the unwinding continues and collects exceptions to |
| 215 | +be handled. When the unwinding is completed all new exceptions are thrown |
| 216 | +from that point. |
| 217 | +
|
| 218 | +For phasers such as C<KEEP> and C<POST> that are run when exiting a scope |
| 219 | +normally, the return value (if any) from that scope is available as the |
| 220 | +current topic within the phaser. |
| 221 | +
|
| 222 | +The topic of the block outside a phaser is still available as C<< |
| 223 | +OUTER::<$_> >>. Whether the return value is modifiable may be a policy of |
| 224 | +the phaser in question. In particular, the return value should not be |
| 225 | +modified within a C<POST> phaser, but a C<LEAVE> phaser could be more |
| 226 | +liberal. |
| 227 | +
|
| 228 | +Any phaser defined in the lexical scope of a method is a closure that closes |
| 229 | +over C<self> as well as normal lexicals. (Or equivalently, an |
| 230 | +implementation may simply turn all such phasers into submethods whose primed |
| 231 | +invocant is the current object.) |
| 232 | +
|
| 233 | +=head2 BEGIN |
| 234 | +=head2 CHECK |
| 235 | +=head2 LINK |
| 236 | +=head2 INIT |
| 237 | +=head2 END |
| 238 | +=head2 ENTER |
| 239 | +=head2 LEAVE |
| 240 | +=head2 KEEP |
| 241 | +=head2 UNDO |
| 242 | +=head2 FIRST |
| 243 | +=head2 NEXT |
| 244 | +=head2 LAST |
| 245 | +=head2 PRE |
| 246 | +=head2 POST |
| 247 | +=head2 CATCH |
| 248 | +=head2 CONTROL |
| 249 | +=head2 COMPOSE |
0 commit comments