'at compile-time' 在 Perl 脚本中的含义是什么?

What is the meaning of 'at compile-time' in Perl scripting?

我读过这篇关于 Perl 的文章:

Perl is an interpreted language and doesn't compile.

我也看到了 at compile-timeat run-time 的讨论。

尤其是当我寻找 userequire 的用法时,它显示出不同之处:

use normally loads the module at compile time whereas require does at run time.

Perl 真的会编译脚本吗? 'at compile-time' 在 Perl 脚本中的含义是什么?

Perl 会在 运行ning 之前编译。通常这是在之前立即完成的。 运行 perl -c 将进行相当基本的代码有效性检查,并突出显示某些 类 错误(通常在我的情况下,缺少分号)。

来自perlrun

After locating your program, Perl compiles the entire program to an internal form. If there are any compilation errors, execution of the program is not attempted. (This is unlike the typical shell script, which might run part-way through before finding a syntax error.)

这包括加载和检查任何导入的模块以进行相同的测试。在 大多数 情况下,这正是您想要的 - 这些 tests/errors 通常 显示塞子,因此在开始执行之前进行检测是好东西。

尤其是当您 use strict;use warnings; 时,您的代码会针对更大范围的错误进行预处理。它是在编译时完成的,如果它发现任何东西,它就会中止。

同样,这 通常 可取的 - 在程序中途被故障绊倒 通常 更烦人,因为你' re 可能处于不一致状态。

然而,正如您所注意到的 - 模块之类的东西可能非常大,因此加载它们可能很有用 'on the fly'。 Perl 可以随你重新定义很多东西——如果你真的想要,你可以在你的代码中 make/change 子程序。

由于所谓的暂停状态问题,"compile time" 永远无法更改子程序并测试其有效性。所以你在 运行 时间加载,但随后必须构建一些更详尽的完整性检查。

看看How a Perl 5 Program Works。 它指出

There are two distinct phases of execution of a Perl 5 program: compile time and runtime.

也说明了compile timeruntime的区别。

Perl 代码在执行前先编译,只是不编译成机器码。有点像Java编译成字节码的方式,但是结果更高级

# B::Concise shows the opcode tree that results from compiling Perl code

$ perl -MO=Concise,-exec -e'print("Hello, world!\n") for 1..3;'
1  <0> enter
2  <;> nextstate(main 1 -e:1) v:{
3  <0> pushmark s
4  <$> const[IV 1] s
5  <$> const[IV 3] s
6  <#> gv[*_] s
7  <{> enteriter(next->b last->e redo->8) lKS/8
c  <0> iter s
d  <|> and(other->8) vK/1
8      <0> pushmark s
9      <$> const[PV "Hello, world!\n"] s
a      <@> print vK
b      <0> unstack v
           goto c
e  <2> leaveloop vK/2
f  <@> leave[1 ref] vKP/REFC
-e syntax OK

当 Perl 被要求执行一个文件时(因为它被传递给 perlrequiredo EXPReval EXPR),它首先编译整个文件, 然后执行它刚刚编译的代码。

如果在编译阶段遇到任何useBEGIN,则use语句或BEGIN块在编译完成后立即执行。

# -c causes the main program to be compiled but not executed.

$ perl -c -E'
   say "abc";
   BEGIN { say "def"; }
   say "ghi";
'
def
-e syntax OK

$ perl -E'
   say "abc";
   BEGIN { say "def"; }
   say "ghi";
'
def
abc
ghi

某些错误可以在编译时检测到。

$ perl -c -E'say "abc" "def";'
String found where operator expected at -e line 1, near ""abc" "def""
        (Missing operator before  "def"?)
syntax error at -e line 1, near ""abc" "def""
-e had compilation errors.

其他人不能。

$ perl -c -E'$x={}; $x->[0]'
-e syntax OK

$ perl -E'$x={}; $x->[0]'
Not an ARRAY reference at -e line 1.