Let's say I want to create a number of types at compile-time, but before that let's test compile-time code with a simpler example:
# in file root.pm6
sub foo($a) { $a.say }
sub EXPORT {
# Things here may be a lot more complex
foo 1;
foo 2;
foo 1;
%( one => 1 )
}
and a module between direct original library and end-user file:
# in file middle.pm6
use root;
class A {} # Do something with stuff from root.pm6
End-user file:
# in file user.pm6
use middle;
Then in command line:
➜ tester perl6 -I. user.pm6
1
2
It seems that third call to foo
was cached and wasn't executed for the third time.
Such behavior makes any relatively complex computations(that are based on code re-use) in sub EXPORT
(as well as in other compile-time areas) impossible.
According to my understanding, compile-time code is meant to be executed normally with its results(e.g. some declarations, tweaks and so on) being accessible from the compiled unit by other modules. However, there is some sort of caching involved too.
The question is, ultimately, "How to achieve what I want" with possible milestones:
1)Is such sort of caching intended?
2)If yes, can it be disabled while having advantages of compile-time code execution? If no, what another workarounds are possible?
UPDATE 1: explaining thing I want more specifically: at compile-time I am parsing a config file and creating types to export. I want those to be pre-compiled, that is the point. Types can be nested and various cases are possible, so I am handing in with a transitional state machine imitation implemented as a simple subroutine with a long given-where
statement, some branches are recursive(bottom is always present). The issue I stuck at is that some branches won't be executed after being fired once, which I was able to golf into simple double foo 1
call I have presented in main question.
UPDATE 2: as raiph mentioned, it works correctly when ran from a command line when level of indirectness between original lib and user-one is 0, but when structure is root lib file that creates types -> middleware lib file that patches those -> end-user(be it a test file or another module
, not all code is executed.
This appears to be a Rakudo bug or something close enough to it.
At least, as advised by Jonathan Worthington, using note
instead of say
makes the example code work as necessary, which clears all implications being made about possible caching being involved.
Maybe you are looking at the INIT
phaser:
INIT {
# Things here may be a lot more complex
foo 1;
foo 2;
foo 1;
%( one => 1 )
}
Which might be a bit too verbose for you:
> use user;
1
2
1
2
1
INIT
is run at runtime. If you want to assign values to variables, it will get the job done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With