接下来的部分介绍怎样使用各种各样的编译器后端。介绍的顺序按照后端的成熟程度排列,所以最为稳定的,经过了验证的后端会最先介绍,还在试验中和没有完成的后端就放到后面描述了。
O模块默认让 -c 开关有效,这防止Perl在编译完代码后运行程序。这也是为什么所有的后端在产生任何输出前都会打印一句:
myperlprogram syntax OK
The Cross Referencing Back End 交叉引用后端
交叉引用后端(B::Xref)生成一个关于你的程序的报表,把各个申明以及子程序,变量(包括格式)的使用情况存入文件中去。举例来说,这有一段摘自对pod2man程序分析后生成的报表(该程序是Perl自带的一个例程):
Subroutine clear_noremap
Package (lexical)
$ready_to_print i1069, 1079
Package main
$& 1086
$. 1086
$0 1086
$1 1087
$2 1085, 1085
$3 1085, 1085
$ARGV 1086
%HTML_Escapes 1085, 1085 这里展示了"clear_noremap" 子程序中变量的使用情况。就像变量 $ready_to_print 是 my() (词法) 的一个变量,在第1069行被引入( 原文用的词是introduced,也就是在 my() 中第一次被定义的意思 ),然后在第1079行该变量被使用了。从主包(main package)中来的变量 $& 又在第1086行被使用, 等等。
行号前面可能会有一个字母作为前缀,它们的意思是:
- i
- 变量首次被引入 (在my()中申明) 。
- &
- 子程序或者方法的引用。
- s
- 定义的子程序。
- r
- 定义的格式。
交叉引用中最为有用的选项就是把报表存入不同的文件,例如要把关于 myperlprogram 的报表存入文件 report 中:
$ perl -MO=Xref,-oreport myperlprogram
The Decompiling Back End 反编译后端
反编译后端将把你的Perl语法树重新变成源代码。生成的源代码会按照某种格式组织,所以这个后端可以用来消除代码中的混乱部分。此后端的基本使用方法如下:
$ perl -MO=Deparse myperlprogram
你也许马上会发现Perl并不知道如何给你的代码分段。你要自己手动添入新行来把这大断的代码分开。然而现在,让我们看看代码只有一行时情况怎样,这个后端会做些什么:
$ perl -MO=Deparse -e '$op=shift⎪⎪die "usage: $0
code [...]";chomp(@ARGV=<>)unless@ARGV; for(@ARGV){$was=$_;eval$op;
die$@ if$@; rename$was,$_ unless$was eq $_}'
-e syntax OK
$op = shift @ARGV ⎪⎪ die("usage: $0 code [...]");
chomp(@ARGV = <ARGV>) unless @ARGV;
foreach $_ (@ARGV) {
$was = $_;
eval $op;
die $@ if $@;
rename $was, $_ unless $was eq $_;
} 这个后端也有几条选项控制生成的代码,举例说,你可以把缩进的尺寸设在4(最大)到2之间:
$ perl -MO=Deparse,-si2 myperlprogram
-p 开关控制在常常可以不加圆括号的地方加上它们:
$ perl -MO=Deparse -e 'print "Hello, world\n"'
-e syntax OK
print "Hello, world\n";
$ perl -MO=Deparse,-p -e 'print "Hello, world\n"'
-e syntax OK
print("Hello, world\n"); 要知道更多,请参考 B::Deparse
Lint 后端
lint 后端 (B::Lint) 检察程序中不好的程序风格。一个程序认为的不好风格可能对另外一个程序员来说是用起来很有效的工具,所以有选项让你设定哪些东东将会受到检查。
要运行一个风格检查器检察你的代码:
$ perl -MO=Lint myperlprogram
要取消对上下文和没有定义的子程序的检查:
$ perl -MO=Lint,-context,-undefined-subs myperlprogram
要知道更多的选项信息,请看 B::Lint
The Simple C Back End 简化的C后端
这个模块用来把你的Perl程序的内部编译状态存储到一个C代码文件中去,而生成的C代码就可以被特定平台上的C编译器转换成一个可执行文件了。最后的程序还会和Perl解释器的库文件静态链接起来,所以它不会节省你的磁盘空间(除非你的Perl是用共享的库文件创建的)或是程序大小,然而,另一方面,程序启动起来会快一些。
"perlcc" 工具缺省是生成以下的可执行文件。
perlcc myperlprogram.pl
The Bytecode Back End 字节码后端
这个模块只有在你能够找到一种方法来装入并运行它生成的字节码时才会显得有用。ByteLoader模块提供了这项功能。
要把Perl转换成可执行的字节码,你可以使用 "perlcc" 的 "-B" 开关:
perlcc -B myperlprogram.pl
字节码是和机器类型无关的,所以一旦你编译了一个模块或是程序,它就可以像Perl源代码一样具有可移植性。(假设那个模块或者程序的使用者有一个足够新的Perl解释器来对字节码进行解码)
有一些选项用来控制要生成的字节码的性质和关于优化方面的参数,要知道这些选项的详细情况,请参考 B::Bytecode
The Optimized C Back End 优化的C后端
优化的C后端按照语法树中运行期代码的路径将你的Perl程序转换成等效的(但是被优化了的)C代码文件。这个C程序会直接对Perl的数据结构进行操作,而且也会链接Perl的解释器的库文件,以支持 eval(), "s///e", "require" 等等。
"perlcc" 工具使用 -O 开关生成这种可执行文件。要编译一个Perl程序(以".pl" 或者".p" 结尾):
perlcc -O myperlprogram.pl
从Perl模块创建一个共享库文件(以 ".pm" 结尾):
perlcc -O Myperlmodule.pm
知道更多,请参考 perlcc 和 B::CC.