I have a Perl script that takes user input and creates another script that will be run at a later date. I'm currently going through and writing tests for these scripts and one of the tests that I would like to perform is checking if the generated script compiles successfully (e.g. perl -c <script>
.) Is there a way that I can have Perl perform a compile on the generated script without having to spawn another Perl process? I've tried searching for answers, but searches just turn up information about compiling Perl scripts into executable programs.
Since version 5.005, Perl has shipped with a module capable of inspecting the optimized parse tree ( B ), and this has been used to write many useful utilities, including a module that lets you turn your Perl into C source code that can be compiled into an native executable.
If you would like to make a call to, or reference, a Perl script from within a different Perl script, you can accomplish this a system(), exec() or the backtick operator to the path for Perl. For example: system("/usr/bin/perl /path/to/my_script.pl ");
The code is bilingual in that it is a perfectly valid shell script and perl program. Let's start by looking at the thing as a shell script. The first line tells the system that this is a shell (/bin/sh) script. The next line tells the shell to execute the perl command with the –x and –S options.
Compiling a script has a lot of side-effects. It results in subs being defined. It results in modules being executed. etc. If you simply want to test whether something compiles, you want a separate interpreter. It's the only way to be sure that one testing one script doesn't cause later tests to give false positives or false negatives.
To execute dynamically generated code, use eval
function:
my $script = join /\n/, <main::DATA>;
eval($script); # 3
__DATA__
my $a = 1;
my $b = 2;
print $a+$b, "\n";
However if you want to just compile or check syntax, then you will not be able to do it within same Perl session.
Function syntax_ok
from library Test::Strict run a syntax check by running perl -c
with an external perl interpreter, so I assume there is no internal way.
Only work-around that may work for you would be:
my $script = join /\n/, <main::DATA>;
eval('return;' . $script);
warn $@ if $@; # syntax error at (eval 1) line 3, near "1
# my "
__DATA__
my $a = 1
my $b = 2;
print $a+$b, "\n";
In this case, you will be able to check for compilation error(s) using $@
, however because the first line of the code is return;
, it will not execute.
Note: Thanks to user mob for helpfull chat and code correction.
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