Documentation for phasers LEAVE

Documentation for phasers LEAVE, assembled from the following types:

language documentation Phasers

From Phasers

(Phasers) phasers LEAVE

Runs at every block exit time (even stack unwinds from exceptions).

So LEAVE phasers for a given block are necessarily evaluated after any CATCH and CONTROL phasers. This includes the LEAVE variants, KEEP and UNDO. POST phasers are evaluated after everything else, to guarantee that even LEAVE phasers can't violate postconditions.

An exception thrown from an ENTER phaser will abort the ENTER queue, but one thrown from a LEAVE phaser will not.

If a POST fails or any kind of LEAVE block throws an exception while the stack is unwinding, the unwinding continues and collects exceptions to be handled. When the unwinding is completed all new exceptions are thrown from that point.

sub answer() {
    LEAVE say I say after the return value.;
 
    42 # this is the return value 
}

Note: be mindful of LEAVE phasers directly in blocks of routines, as they will get executed even when an attempt to call the routine with wrong arguments is made:

sub foo (Int{
    say "Hello!";
    LEAVE say "oh noes!"
}
try foo rand# OUTPUT: «oh noes!␤» 

Although the subroutine's body did not get run, because the sub expects an Int and rand returned a Num, its block was entered and left (when param binding failed), and so the LEAVE phaser was run.