我读过有关perl的信息:
Perl是一种解释型语言,无法编译。
我还看到了关于at compile-time
和at run-time
的讨论。
特别是当我寻找use
和require
的使用时,它会显示出不同之处:
use
通常在编译时加载模块 ,而require
在运行时 。
所以我的问题是Perl真的编译脚本吗? perl脚本编写中“编译时”的含义是什么?
答案 0 :(得分:5)
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执行文件时(因为它已传递给perl
,require
,do EXPR
或eval EXPR
),它首先编译整个文件,然后执行它刚编译的代码。
如果在编译阶段遇到任何use
或BEGIN
,则在完成编译后会立即执行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.
答案 1 :(得分:4)
Perl在运行之前编译。通常这是在之前完成的。运行perl -c
将执行相当基本的代码有效性检查,并将突出显示某些类型的错误(通常在我的情况下,缺少分号)。
来自perlrun
:
找到程序后,Perl会将整个程序编译为内部表单。如果存在任何编译错误,则不会尝试执行程序。 (这与典型的shell脚本不同,后者可能会在找到语法错误之前部分运行。)
包括加载和检查任何导入的模块以进行相同的测试。在大多数情况下,这正是您想要的 - 这些测试/错误通常显示停止者,因此在开始执行之前进行检测是一件好事。
特别是当您use strict;
和use warnings;
时,您的代码会针对更广泛的错误进行预处理。它在编译时完成,如果发现任何内容,它将中止。
同样,这通常是理想的 - 在程序中途绊倒故障通常更难以理清,因为你可能处于不一致的状态。
然而,正如您所注意到的那样 - 模块之类的东西可能非常大,因此可以在运行时加载它们。 Perl可以在你去的时候重新定义一堆东西 - 如果你真的想要你可以在你的代码中制作/更改子程序。
由于所谓的暂停状态问题,在“编译时”不能对子例程进行更改并测试其有效性。因此,您在运行时加载,但然后必须构建一些更详尽的完整性检查。
答案 2 :(得分:2)