BEGIN {...} * This block is executed once when the application is compiled, and the last calculated result (as in the future with blocks marked with an asterisk) can be used as a result to assign a variable:
say"Test say"; my $block = BEGIN { say"Compile say"; "Compile time " ~ now; } say $block;
In this case, the variable block will be assigned a string reflecting the time of compilation (And as I understood, the block itself is executed during compilation, and when the script is executed, the variable is assigned to the already calculated value). As a result, we will see on the screen:
Compile say Test say Compile time Instant:1377026323.088
Moreover, if an exception occurs inside the BEGIN block:
say"Test say"; my $block = BEGIN { die"Compile die"; "Compile time " ~ now; } say $block;
Then on the screen we will not see the words “Test say”, but immediately “Compile die”, although the output occurs earlier than the assignment of the result of the BEGIN block. Well, the last example of this block to dispel possible doubts:
say"Test say"; BEGIN { say"Compile say"; } say"Test say 2"; BEGIN { say"Compile say 2"; }
As a result, we will see on the screen:
Compile say Compile say2 Test say Test say2
CHECK {...} * It is similar to the previous one, but the actions are performed after the compilation is performed but before the execution of the script itself, however, as I noted in the reverse order in the code:
say"Test say"; BEGIN { say"Compile say"; } CHECK { say"Check say"; } say"Test say 2"; BEGIN { say"Compile say 2"; } CHECK { say"Check say 2"; }
As a result, we will see on the screen:
Compile say Compile say2 Check say2 Check say Test say Test say2
INIT {...} * This block is executed when running the script:
say"Test say"; BEGIN { say"Compile say"; } CHECK { say"Check say"; } INIT { say"Init say"; } say"Test say 2"; BEGIN { say"Compile say 2"; } CHECK { say"Check say 2"; } INIT { say"Init say 2"; }
As a result, the output is as follows:
Compile say Compile say2 Check say2 Check say Init say Init say2 Test say Test say2
END {...} The block is executed when the script is stopped. It should be noted that it is executed in the same way as in the case of CHECK in the reverse order as they were encountered in the script, and one more important thing - this block is executed even if an exception occurred in the script:
say"Test say"; BEGIN { say"Compile say"; } CHECK { say"Check say"; } INIT { say"Init say"; } END { say"End say"; } say"Test say 2"; BEGIN { say"Compile say 2"; } CHECK { say"Check say 2"; } INIT { say"Init say 2"; } END { say"End say 2"; } die"test die";
As a result, we see on the screen:
Compile say Compile say2 Check say2 Check say Init say Init say2 Test say Test say2 test die in block at bla\bla\bla\perl.p6:37 End say2 End say
ENTER {...} * This block is executed during any execution of a block in which an ENTER block is nested:
loop (my $i=0; $i <4; $i++) { ENTER { say $i; } say"Another loop entry"; } ENTER { say"Test Enter"; }
The output of this script:
Test Enter 0 Another loop entry 1 Another loop entry 2 Another loop entry 3 Another loop entry
It is also worth noting that Phasers can be put into each other.
LEAVE {...} It is executed when the block in which LEAVE was nested is completed. It was here that I once again ran into problems, because of which I postponed the study last time - I again began to receive vague errors if I put a wrong space. And the example with the LEAVE block was simply not compiled for me, notifying me of an error with the wrong number of parameters for the return operator, which I by the way did not try to use. But I'll give an example all the same:
If anyone can compile this, please tell us in the comments. As I later found out, the part associated with exiting the block does not work. But move on:
KEEP {...} This block is executed when the entire block is successfully executed (it was not able to check how exactly the success is determined, since the script using such a block is not compiled).
UNDO {...} It is similar to the previous block, but if the execution was not completed successfully. The example also does not compile.
FIRST {...} * This block is executed only when the block is first launched, in which FIRST is nested:
Test keep Another loop entry Another loop entry Another loop entry Another loop entry
Also in a separate list are displayed operators that act like Phasers, which are written in lower case:
do {...} * Performs all operations in the block, and the result is in the form of a term. Usage example:
if ( do {my $a = 10; $a = $a*2;} == 20) { say"It's ok"; }
So we put the calculation inside the if block, and the do block itself can be used later for comparison. An example is of course very bad for your fingers (you can use it with a ruler for this), but in order to show why it can be used, the example will fit.
once {...} * This block will have to be executed only once. Unfortunately, I could not verify it, since we do not compile the example:
my $i = once { say"Test once"; }; $i(); $i(); $i();
Complains that could not find the & once function.
try {...} * A block familiar in the previous article ignoring all exceptions.
lazy {...} * According to the description should return the "promise" of implementation. Unfortunately, the result is for him as with the 'once' block. As I understand this unit should help us in the organization of "lazy calculations."
async {...} Executes a block in a new thread. Unfortunately, again, I could not compile the example. But now I have an idea of ​​how work with threads will occur.
Well, perhaps it's time to finish. Somehow even a long post turned out because of examples, but I hope you enjoyed it.