This is related to this issue in the Perl 6 documentation repo
It's not too clear the phase in which BEGIN
blocks are actually run. Documentation says "compile time", but Perl is precompiled, so that might actually be precompile time. As a matter of fact, let's use this code
unit module Beginner;
BEGIN {
say "This is where all started";
}
from here
require Beginner;
say "Begun";
in a fresh directory (rm -rf .precomp
run). It outputs:
This is where all started
Begun
By now, the
.precomp
directory that holds the cache has already been created.
So let's use it from here:
use Beginner;
say "Already started";
And it obviously returns just Already started
. (Same happens if we run the first program).
This might be a problem, because the user might not know in advance if precompilation might take place or not, which in turn means that it's not certain when "compile time" is taking place. Anyway, the question is: how can we formulate this correctly to explain it in the documentation? Also, should the use of BEGIN
be encouraged (since values computed there are going to be stored in the precompilation cache and thus effectively eliminated from runtime) or discouraged? Is there some good use case for this?
BEGIN
happens at compile time, and as you have observed correctly, this can be precompilation time.
I don't see any problem with that, as long as you don't assume compilation happens at script startup. Just like C++ templates are evaluated at compilation time, which is usually very different from execution time.
Also, should the use of BEGIN be encouraged (since values computed there are going to be stored in the precompilation cache and thus effectively eliminated from runtime) or discouraged
Everything should be encouraged for their appropriate use cases, and discouraged for everything else.
If you want to run something at program startup, use INIT
, not BEGIN
.
Is there some good use case for this?
Lots of meta programming can (and should) be done at compile time, for example creating a list of methods and attributes based on a fixed list of names. Doing that at every program startup would be a waste, and other parts of the program might need the complete type at compilation time.