内容

名称

perlfaq3 - 编程工具

版本

版本 5.20210520

描述

本节 FAQ 回答与程序员工具和编程支持相关的问题。

我该如何做(任何事)?

您是否查看过 CPAN(参见 perlfaq2)?很有可能有人已经编写了一个可以解决您问题的模块。您是否阅读了相应的联机帮助页?这是一个简短的索引

基础
perldata - Perl 数据类型
perlvar - Perl 预定义变量
perlsyn - Perl 语法
perlop - Perl 运算符和优先级
perlsub - Perl 子例程
执行
perlrun - 如何执行 Perl 解释器
perldebug - Perl 调试
函数
perlfunc - Perl 内置函数
对象
perlref - Perl 引用和嵌套数据结构
perlmod - Perl 模块(包和符号表)
perlobj - Perl 对象
perltie - 如何将对象类隐藏在简单变量中
数据结构
perlref - Perl 引用和嵌套数据结构
perllol - 在 Perl 中操作数组的数组
perldsc - Perl 数据结构食谱
模块
perlmod - Perl 模块(包和符号表)
perlmodlib - 创建新的 Perl 模块和查找现有的模块
正则表达式
perlre - Perl 正则表达式
perlfunc - Perl 内置函数>
perlop - Perl 运算符和优先级
perllocale - Perl 本地化处理(国际化和本地化)
迁移到 perl5
perltrap - Perl 陷阱,谨防
perl
与 C 语言链接
perlxstut - 编写 XSUB 的教程
perlxs - XS 语言参考手册
perlcall - 从 C 调用 Perl 的约定
perlguts - Perl API 简介
perlembed - 如何在 C 程序中嵌入 Perl
各种

http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz (不是手册页,但仍然有用,是关于 Perl 技术的各种文章的集合)

Perl 手册页集的粗略目录在 perltoc 中。

如何以交互方式使用 Perl?

典型方法是使用 Perl 调试器,在 perldebug(1) 手册页中描述,在一个“空”程序上,像这样

perl -de 42

现在只需输入任何合法的 Perl 代码,它就会立即被评估。您还可以检查符号表、获取堆栈回溯、检查变量值、设置断点以及符号调试器中通常发现的其他操作。

您还可以使用 Devel::REPL,它是一个 Perl 的交互式 shell,通常称为 REPL - 读取、评估、打印、循环。它提供了各种方便的功能。

如何找到我的系统上安装了哪些模块?

从命令行,您可以使用 cpan 命令的 -l 开关

$ cpan -l

您还可以使用 cpan-a 开关来创建一个 CPAN.pm 理解并可以用来重新安装每个模块的自动捆绑文件

$ cpan -a

在 Perl 程序中,您可以使用 ExtUtils::Installed 模块来显示所有已安装的分布,尽管这可能需要一段时间才能完成其操作。随 Perl 附带的标准库只显示为“Perl”(尽管您可以使用 Module::CoreList 获取这些库)。

use ExtUtils::Installed;

my $inst    = ExtUtils::Installed->new();
my @modules = $inst->modules();

如果您想要所有 Perl 模块文件名的列表,您可以使用 File::Find::Rule

use File::Find::Rule;

my @files = File::Find::Rule->
    extras({follow => 1})->
    file()->
    name( '*.pm' )->
    in( @INC )
    ;

如果您没有该模块,您可以使用 File::Find 做同样的事情,它是标准库的一部分

use File::Find;
my @files;

find(
    {
    wanted => sub {
        push @files, $File::Find::fullname
        if -f $File::Find::fullname && /\.pm$/
    },
    follow => 1,
    follow_skip => 2,
    },
    @INC
);

print join "\n", @files;

如果您只需要快速检查一下模块是否可用,您可以检查其文档。如果您能阅读文档,该模块很可能已安装。如果您无法阅读文档,该模块可能没有文档(在极少数情况下)。

$ perldoc Module::Name

您还可以尝试在一行代码中包含该模块,以查看 perl 是否找到了它

$ perl -MModule::Name -e1

(如果您没有收到“无法在 @INC 中找到...”的错误消息,那么 Perl 找到了您请求的模块名称。)

如何调试我的 Perl 程序?

(由 brian d foy 贡献)

在您进行任何其他操作之前,您可以通过确保让 Perl 告知您代码中的问题区域来帮助自己。通过开启警告和严格模式,您可以在问题变得太大之前解决许多问题。您可以在 strictwarnings 中找到更多关于这些内容的信息。

#!/usr/bin/perl
use strict;
use warnings;

除此之外,最简单的调试器是 print 函数。使用它在运行程序时查看值。

print STDERR "The value is [$value]\n";

Data::Dumper 模块可以美化打印 Perl 数据结构。

use Data::Dumper qw( Dumper );
print STDERR "The hash is " . Dumper( \%hash ) . "\n";

Perl 带有一个交互式调试器,您可以使用 -d 开关启动它。它在 perldebug 中有详细说明。

如果您想要一个图形用户界面并且您有 Tk,您可以使用 ptkdb。它在 CPAN 上并且可以免费获得。

如果您需要更复杂和可控的东西,Leon Brocard 的 Devel::ebug(您可以使用 -D 开关作为 -Debug 调用它)为您提供了编写自己的程序(无需太多痛苦和折磨)所需的一切的编程钩子。

您还可以使用商业调试器,例如 Affrus(Mac OS X)、Activestate 的 Komodo(Windows 和 Mac OS X)或 EPIC(大多数平台)。

如何分析我的 Perl 程序?

(由 brian d foy 贡献,更新于 2008 年 7 月 25 日星期五 12:22:26 PDT)

Devel 命名空间有几个模块,您可以使用它们来分析您的 Perl 程序。

Devel::NYTProf(纽约时报分析器)同时进行语句和子程序分析。它可以在 CPAN 上获得,您也可以使用 -d 开关调用它。

perl -d:NYTProf some_perl.pl

它创建了一个分析信息的数据库,您可以将其转换为报告。nytprofhtml 命令将数据转换为类似于 Devel::Cover 报告的 HTML 报告。

nytprofhtml

您可能也对使用 Benchmark 来测量和比较代码片段感兴趣。

您可以在Programming Perl的第20章或Mastering Perl的第5章中了解更多关于剖析的信息。

如果您需要创建一种特殊的剖析器,perldebguts 文档介绍了如何创建自定义调试器。brian d foy 在The Perl Journal中描述了这个过程,名为“创建 Perl 调试器”,http://www.ddj.com/184404522,以及“Perl 中的剖析”,http://www.ddj.com/184404580

Perl.com 上有两篇关于剖析的有趣文章:“剖析 Perl”,作者是 Simon Cozens,https://perldotcom.perl5.cn/pub/2004/06/25/profiling.html/,以及“调试和剖析 mod_perl 应用程序”,作者是 Frank Wiles,https://perldotcom.perl5.cn/pub/a/2006/02/09/debug_mod_perl.html

Randal L. Schwartz 在“加速您的 Perl 程序”中写了关于剖析的文章,该文章发表在Unix Review上,http://www.stonehenge.com/merlyn/UnixReview/col49.html,以及“通过覆盖进行 Template Toolkit 剖析”,该文章发表在Linux Magazine上,http://www.stonehenge.com/merlyn/LinuxMag/col75.html

如何交叉引用我的 Perl 程序?

可以使用 B::Xref 模块为 Perl 程序生成交叉引用报告。

perl -MO=Xref[,OPTIONS] scriptname.plx

Perl 有美化打印机(格式化程序)吗?

Perl::Tidy 带有一个 perl 脚本 perltidy,它可以缩进和重新格式化 Perl 脚本,使其更容易阅读,因为它试图遵循 perlstyle 的规则。如果您编写 Perl,或者花很多时间阅读 Perl,您可能会发现它很有用。

当然,如果您只是遵循 perlstyle 中的指南,您就不需要重新格式化。在编写代码时格式化代码的习惯将有助于防止错误。您的编辑器可以并且应该在这方面帮助您。emacs 的 perl-mode 或更新的 cperl-mode 可以为大多数(但不是全部)代码提供显著的帮助,即使是可编程性较低的编辑器也可以提供显著的帮助。Tom Christiansen 和许多其他 VI 用户都赞成在 vi 及其克隆中使用以下设置

set ai sw=4
map! ^O {^M}^[O^T

将这些内容放入您的 .exrc 文件中(用控制字符替换脱字符号),然后就可以开始使用了。在插入模式下,^T 用于缩进,^D 用于取消缩进,^O 用于块缩进 - 就像这样。一个更完整的示例,带有注释,可以在 http://www.cpan.org/authors/id/T/TO/TOMC/scripts/toms.exrc.gz 找到。

是否有 IDE 或 Windows Perl 编辑器?

Perl 程序只是纯文本,所以任何编辑器都可以。

如果您使用的是 Unix,那么您已经拥有了一个 IDE - Unix 本身。Unix 的理念是使用多个小型工具,每个工具都只做一件事,并且做得很好。就像木匠的工具箱一样。

如果您想要一个 IDE,请查看以下内容(按字母顺序排列,不按偏好顺序排列)

Eclipse

http://e-p-i-c.sf.net/

Eclipse Perl 集成项目将 Perl 编辑/调试与 Eclipse 集成在一起。

Enginsite

http://www.enginsite.com/

EngInSite 的 Perl 编辑器是一个完整的集成开发环境 (IDE),用于创建、测试和调试 Perl 脚本;该工具可在 Windows 9x/NT/2000/XP 或更高版本上运行。

IntelliJ IDEA

https://plugins.jetbrains.com/plugin/7796

Camelcade 插件在 IntelliJ IDEA 和其他 JetBrains IDE 中提供 Perl5 支持。

Kephra

http://kephra.sf.net

使用 wxWidgets 和 Scintilla 用 Perl 编写的 GUI 编辑器,具有许多较小的功能。旨在提供基于 Perl 原则的 UI,例如 TIMTOWTDI 和“简单的事情应该简单,困难的事情应该有可能”。

Komodo

http://www.ActiveState.com/Products/Komodo/

ActiveState 的跨平台(截至 2004 年 10 月,包括 Windows、Linux 和 Solaris)多语言 IDE 具有 Perl 支持,包括正则表达式调试器和远程调试。

Notepad++

http://notepad-plus.sourceforge.net/

Open Perl IDE

http://open-perl-ide.sourceforge.net/

Open Perl IDE 是一个集成开发环境,用于在 Windows 95/98/NT/2000 下使用 ActiveState 的 ActivePerl 发行版编写和调试 Perl 脚本。

OptiPerl

http://www.optiperl.com/

OptiPerl 是一个 Windows IDE,具有模拟的 CGI 环境,包括调试器和语法高亮编辑器。

Padre

http://padre.perlide.org/

Padre 是一个用 Perl 编写的跨平台 Perl IDE,使用 wxWidgets 提供原生外观和感觉。它是根据 Artistic License 开源的。它是较新的 Perl IDE 之一。

PerlBuilder

http://www.solutionsoft.com/perl.htm

PerlBuilder 是一个支持 Perl 开发的 Windows 集成开发环境。

visiPerl+

http://helpconsulting.net/visiperl/index.html

来自 Help Consulting,适用于 Windows。

Visual Perl

http://www.activestate.com/Products/Visual_Perl/

Visual Perl 是 ActiveState 的 Visual Studio.NET 插件。

Zeus

http://www.zeusedit.com/lookmain.html

Zeus for Windows 是另一个支持 Perl 的 Win32 多语言编辑器/IDE。

对于编辑器:如果您使用的是 Unix,您可能已经拥有 vi 或 vi 克隆,以及可能还有 emacs,因此您可能不需要下载任何东西。在任何 emacs 中,cperl-mode(M-x cperl-mode)为您提供了任何编辑器中可能最好的 Perl 编辑模式。

如果您使用的是 Windows,您可以使用任何允许您使用纯文本工作的编辑器,例如 NotePad 或 WordPad。文字处理器,例如 Microsoft Word 或 WordPerfect,通常不起作用,因为它们会插入各种幕后信息,尽管有些允许您将文件保存为“纯文本”。您还可以下载专门为编程设计的文本编辑器,例如 Textpad(http://www.textpad.com/)和 UltraEdit(http://www.ultraedit.com/),等等。

如果您使用的是 MacOS,则适用相同的注意事项。MacPerl(用于经典环境)附带一个简单的编辑器。流行的外部编辑器是 BBEdit(http://www.barebones.com/products/bbedit/)或 Alpha(http://www.his.com/~jguyer/Alpha/Alpha8.html)。MacOS X 用户也可以使用 Unix 编辑器。

GNU Emacs

http://www.gnu.org/software/emacs/windows/ntemacs.html

MicroEMACS

http://www.microemacs.de/

XEmacs

http://www.xemacs.org/Download/index.html

Jed

http://space.mit.edu/~davis/jed/

或 vi 克隆,例如

Vim

http://www.vim.org/

Vile

http://invisible-island.net/vile/vile.html

以下是支持 Perl 的 Win32 多语言编辑器/IDE

MultiEdit

http://www.MultiEdit.com/

SlickEdit

http://www.slickedit.com/

ConTEXT

http://www.contexteditor.org/

还有一个用 Perl 编写的 toyedit 文本小部件,它与 CPAN 上的 Tk 模块一起分发。ptkdb(http://ptkdb.sourceforge.net/)是一个基于 Perl/Tk 的调试器,它充当某种开发环境。Perl Composer(http://perlcomposer.sourceforge.net/)是 Perl/Tk GUI 创建的 IDE。

除了编辑器/IDE 之外,您可能还对 Win32 的更强大的 shell 环境感兴趣。您的选择包括

bash

来自 Cygwin 包(http://cygwin.com/

zsh

http://www.zsh.org/

Cygwin 受 GNU 通用公共许可证的约束(但这对 Perl 使用来说无关紧要)。Cygwin 包含(除了 shell 之外)一套全面的标准 Unix 工具集实用程序。

BBEdit 和 TextWrangler

是 OS X 的文本编辑器,具有 Perl 敏感模式(http://www.barebones.com/)。

在哪里可以获得 Perl 宏用于 vi?

有关 Tom Christiansen 的 vi 配置文件的完整版本,请参见 http://www.cpan.org/authors/id/T/TO/TOMC/scripts/toms.exrc.gz,这是 vi 模拟器的标准基准文件。该文件在 nvi 上运行效果最佳,nvi 是当前版本的 vi,来自伯克利,它可以与嵌入式 Perl 解释器一起构建,请参见 http://www.cpan.org/src/misc/

在哪里可以获得 perl-mode 或 cperl-mode 用于 emacs?

从 Emacs 版本 19 补丁级别 22 开始,就内置了 perl-mode.el 和对 Perl 调试器的支持。这些应该与标准 Emacs 19 发行版一起提供。

请注意,emacs 的 perl-mode 会对 "main'foo"(单引号)产生问题,并弄乱缩进和突出显示。您可能已经在新的 Perl 代码中使用 "main::foo" 了,所以这应该不是问题。

有关 CPerlMode,请参见 http://www.emacswiki.org/cgi-bin/wiki/CPerlMode

如何使用 curses 与 Perl?

来自 CPAN 的 Curses 模块为 curses 库提供了一个动态加载的对象模块接口。可以在目录 http://www.cpan.org/authors/id/T/TO/TOMC/scripts/rep.gz 中找到一个小型演示;该程序重复一个命令并根据需要更新屏幕,使 rep ps axu 类似于 top

如何在Perl中编写GUI(X,Tk,Gtk等)?

(由Ben Morrow贡献)

有很多模块可以让你在Perl中编写GUI。大多数GUI工具包都有Perl接口:以下是一个不完整的列表。

Tk

它在Unix和Windows下工作,当前版本在Windows下的外观比以前好多了。不过,一些GUI元素仍然感觉不太对劲。该接口非常自然且“Perl式”,使其易于在只需要简单GUI的小脚本中使用。它已经有一段时间没有更新了。

Wx

这是跨平台wxWidgets工具包(http://www.wxwidgets.org)的Perl绑定。它在Unix、Win32和Mac OS X下工作,使用原生小部件(Unix下的Gtk)。该接口紧密遵循C++接口,但对于不熟悉该库的人来说,文档有点稀疏,主要只是将你引导到C++文档。

Gtk和Gtk2

这些是Gtk工具包(http://www.gtk.org)的Perl绑定。版本1和2之间的接口发生了重大变化,因此它们有单独的Perl模块。它在Unix、Win32和Mac OS X下运行(目前它在Mac OS上需要X服务器,但正在进行“原生”移植),并且小部件在每个平台上的外观都相同:即它们不匹配原生小部件。与Wx一样,Perl绑定紧密遵循C API,并且文档要求你阅读C文档才能理解它。

Win32::GUI

它提供了从Perl访问大多数Win32 GUI小部件的功能。显然,它只在Win32下运行,并使用原生小部件。Perl接口并没有真正遵循C接口:它变得更加Perl式,并且文档相当不错。更高级的功能可能需要熟悉C Win32 API或参考MSDN。

CamelBones

CamelBones(http://camelbones.sourceforge.net)是Mac OS X的Cocoa GUI工具包的Perl接口,因此可用于在Mac OS X上生成原生GUI。它不在CPAN上,因为它需要CPAN.pm不知道如何安装的框架,但安装是通过标准的OSX软件包安装程序进行的。Perl API再次非常接近它包装的ObjC API,并且文档只是告诉你如何从一个翻译到另一个。

Qt

TrollTech 的 Qt 工具包有一个 Perl 接口,但它似乎没有得到维护。

Athena

Sx 是一个与 X 一起提供的 Athena 小部件集的接口,但它似乎现在已经不再被广泛使用。

如何使我的 Perl 程序运行更快?

最好的方法是提出更好的算法。这通常可以带来显著的差异。Jon Bentley 的书《编程珠玑》(不是拼写错误!)也提供了一些关于优化的良好建议。关于基准测试的建议归结为:进行基准测试和分析,以确保你正在优化正确的部分,寻找更好的算法而不是微调你的代码,如果所有方法都失败,请考虑购买更快的硬件。如果你还没有这样做,你可能需要阅读之前问题“如何分析我的 Perl 程序?”的答案。

另一种方法是自动加载很少使用的 Perl 代码。为此,请参阅标准发行版中的 AutoSplit 和 AutoLoader 模块。或者,你可以找到瓶颈,并考虑只用 C 语言编写那部分代码,就像我们过去在 C 代码中找到瓶颈并用汇编语言编写它们一样。类似于用 C 语言重写,具有关键部分的模块可以用 C 语言编写(例如,来自 CPAN 的 PDL 模块)。

如果你当前将你的 perl 可执行文件链接到共享的 libc.so,你通常可以通过重建它以链接到静态 libc.a 来获得 10-25% 的性能提升。这将使 perl 可执行文件更大,但你的 Perl 程序(和程序员)可能会感谢你。有关更多信息,请参阅源代码发行版中的 INSTALL 文件。

undump 程序是以前为了加快 Perl 程序速度而进行的一种尝试,它将已编译的形式存储到磁盘。这不再是一种可行的选择,因为它只在少数架构上有效,而且本身也不是一个好的解决方案。

如何使我的 Perl 程序占用更少的内存?

在时间-空间权衡方面,Perl 几乎总是倾向于用内存解决问题。Perl 中的标量比 C 中的字符串占用更多内存,数组比标量占用更多内存,哈希占用更多内存。虽然还有很多工作要做,但最近的版本一直在解决这些问题。例如,从 5.004 开始,重复的哈希键在所有使用它们的哈希之间共享,因此不需要重新分配。

在某些情况下,使用 substr() 或 vec() 来模拟数组可能非常有利。例如,一个包含一千个布尔值的数组将占用至少 20,000 字节的空间,但它可以变成一个 125 字节的位向量——节省了大量的内存。标准的 Tie::SubstrHash 模块也可以帮助某些类型的数据结构。如果你正在使用专业的数据结构(例如矩阵),在 C 中实现这些结构的模块可能比等效的 Perl 模块占用更少的内存。

另一个尝试的方法是了解你的 Perl 是使用系统 malloc 还是 Perl 内置的 malloc 编译的。无论哪种情况,尝试使用另一种方法,看看是否有所不同。有关 malloc 的信息在源代码分发包中的 INSTALL 文件中。你可以通过输入 perl -V:usemymalloc 来查看是否正在使用 perl 的 malloc。

当然,节省内存的最佳方法是首先不要做任何浪费内存的事情。良好的编程习惯可以在这方面起到很大的作用。

不要一次性读取整个文件!

如果你可以逐行处理文件,就不要将整个文件读入内存。或者更具体地说,使用这样的循环

#
# Good Idea
#
while (my $line = <$file_handle>) {
   # ...
}

而不是这样

#
# Bad Idea
#
my @data = <$file_handle>;
foreach (@data) {
    # ...
}

当你处理的文件很小时,用哪种方式并不重要,但当文件开始变大时,就会有很大的区别。

选择性地使用 map 和 grep

记住,map 和 grep 都期望一个 LIST 参数,所以这样做

@wanted = grep {/pattern/} <$file_handle>;

会导致整个文件被一次性读取。对于大型文件,最好使用循环

while (<$file_handle>) {
        push(@wanted, $_) if /pattern/;
}
避免不必要的引号和字符串化

除非绝对必要,否则不要对大型字符串加引号

my $copy = "$large_string";

会创建 $large_string 的两个副本(一个用于 $copy,另一个用于引号),而

my $copy = $large_string;

只创建一个副本。

大型数组的字符串化也是如此

{
local $, = "\n";
print @big_array;
}

比以下两种方法都要节省内存

print join "\n", @big_array;

{
local $" = "\n";
print "@big_array";
}
按引用传递

按引用传递数组和哈希,而不是按值传递。一方面,这是在单个调用/返回中传递多个列表或哈希(或两者)的唯一方法。它还避免了创建所有内容的副本。然而,这需要一些判断,因为任何更改都会传播回原始数据。如果你真的想修改(即,修改)一个副本,你将不得不牺牲创建副本所需的内存。

将大型变量绑定到磁盘

对于“大型”数据存储(即超过可用内存的数据存储),请考虑使用其中一个 DB 模块将其存储在磁盘上,而不是在 RAM 中。这会对访问时间造成影响,但这可能比由于大量交换而导致硬盘崩溃要好。

返回对局部或词法数据的引用安全吗?

是的。Perl 的垃圾回收系统会处理这个问题,因此一切都会正常运行。

sub makeone {
    my @a = ( 1 .. 10 );
    return \@a;
}

for ( 1 .. 10 ) {
    push @many, makeone();
}

print $many[4][5], "\n";

print "@many\n";

如何释放数组或哈希,以便我的程序缩小?

(由 Michael Carman 贡献)

通常你不能。分配给词法变量(即 my() 变量)的内存即使超出范围也不能回收或重用。它被保留以防变量回到作用域。分配给全局变量的内存可以通过使用 undef() 和/或 delete() 重用(在你的程序中)。

在大多数操作系统上,分配给程序的内存永远无法返回给系统。这就是为什么长时间运行的程序有时会重新执行自身的原因。一些操作系统(特别是使用 mmap(2) 为分配大块内存的系统)可以回收不再使用的内存,但在这些系统上,perl 必须配置并编译为使用操作系统的 malloc,而不是 perl 的。

总的来说,内存分配和释放不是你在 Perl 中需要过多担心的事情。

另见“如何使我的 Perl 程序占用更少的内存?”

如何使我的 CGI 脚本更高效?

除了使一般 Perl 程序更快或更小的正常措施外,CGI 程序还存在其他问题。它可能每秒运行多次。鉴于每次运行都需要重新编译,并且通常会分配 1 MB 或更多系统内存,这可能是致命的。编译成 C **不会帮助你**,因为进程启动开销是瓶颈所在。

有三种流行的方法可以避免这种开销。一种解决方案涉及运行 Apache HTTP 服务器(可从 http://www.apache.org/ 获得)以及 mod_perl 或 mod_fastcgi 插件模块。

使用 mod_perl 和 Apache::Registry 模块(与 mod_perl 一起分发),httpd 将运行一个嵌入式 Perl 解释器,该解释器会预编译你的脚本,然后在同一个地址空间内执行它,而无需分叉。Apache 扩展还允许 Perl 访问内部服务器 API,因此用 Perl 编写的模块可以做任何用 C 编写的模块可以做的事情。有关 mod_perl 的更多信息,请参见 http://perl.apache.org/

使用 FCGI 模块(来自 CPAN)和 mod_fastcgi 模块(可从 http://www.fastcgi.com/ 获取),您的每个 Perl 程序都将成为一个永久的 CGI 守护进程。

最后,Plack 是一个 Perl 模块和工具包,包含 PSGI 中间件、助手和 Web 服务器适配器,允许您轻松部署可以持续运行的脚本,并提供有关使用哪个 Web 服务器的灵活性。它可以使现有的 CGI 脚本在进行最小的更改的情况下享受这种灵活性,或者可以与现代 Perl Web 框架一起使用,使使用 Perl 编写和部署 Web 服务变得轻而易举。

这些解决方案可能会对您的系统以及您编写 CGI 程序的方式产生深远的影响,因此请谨慎地研究它们。

另请参阅 http://www.cpan.org/modules/by-category/15_World_Wide_Web_HTML_HTTP_CGI/

如何隐藏我的 Perl 程序的源代码?

删除它。:-) 说真的,有很多(大多不令人满意)的解决方案,它们具有不同程度的“安全性”。

首先,您不能撤销读取权限,因为源代码必须可读才能被编译和解释。(但这并不意味着 CGI 脚本的源代码可以被网络上的人读取,而只能被有权访问文件系统的人读取。)因此,您必须将权限保留在友好的 0755 级别。

有些人认为这是一个安全问题。如果您的程序执行不安全的操作,并依赖于人们不知道如何利用这些不安全性,那么它就不安全。通常,即使不查看源代码,也可能有人确定不安全的操作并利用它们。通过模糊来实现安全性,即隐藏错误而不是修复错误,实际上几乎没有安全性可言。

您可以尝试使用源代码过滤器进行加密(从 Perl 5.8 开始,Filter::Simple 和 Filter::Util::Call 模块包含在标准发行版中),但任何优秀的程序员都可以解密它。您可以尝试使用后面在 perlfaq3 中描述的字节码编译器和解释器,但好奇的人可能仍然能够反编译它。您可以尝试使用后面描述的原生代码编译器,但破解者可能能够反汇编它。这些对想要获取您代码的人来说难度各不相同,但没有一种能够完全隐藏它(这适用于所有语言,而不仅仅是 Perl)。

恢复 Perl 程序的源代码非常容易。您只需将程序提供给 perl 解释器并使用 B:: 层次结构中的模块。B::Deparse 模块应该能够抵御大多数隐藏源代码的尝试。同样,这并非 Perl 独有。

如果您担心有人利用您的代码获利,那么最重要的是,除了限制性许可证之外,没有任何东西可以为您提供法律保障。对您的软件进行许可并添加一些威胁性的声明,例如“这是 XYZ 公司的未公开专有软件。您访问它并不意味着您有权使用它等等”。当然,我们不是律师,因此如果您想确保您的许可证措辞在法庭上站得住脚,您应该咨询律师。

如何将我的 Perl 程序编译成字节码或 C 代码?

(由 brian d foy 贡献)

一般来说,您无法做到这一点。不过,有一些方法可能适合您的情况。人们通常会问这个问题,因为他们希望在不公开源代码的情况下分发他们的作品,而大多数解决方案都是用磁盘空间换取便利性。您可能也不会看到太多速度提升,因为大多数解决方案只是在最终产品中捆绑了一个 Perl 解释器(但请参阅 "如何使我的 Perl 程序运行得更快?")。

Perl 存档工具包是 Perl 的 Java JAR 等效工具。它可以免费获得,并且在 CPAN 上( https://metacpan.org/pod/PAR )。

也有一些商业产品可能适合你,不过你需要购买许可证。

ActiveState 的 Perl Dev Kit ( http://www.activestate.com/Products/Perl_Dev_Kit/ ) 可以“将你的 Perl 程序转换为适用于 HP-UX、Linux、Solaris 和 Windows 的可执行文件”。

Perl2Exe ( http://www.indigostar.com/perl2exe.htm ) 是一个命令行程序,用于将 Perl 脚本转换为可执行文件。它同时支持 Windows 和 Unix 平台。

如何在 [MS-DOS,NT,...] 上使用 #!perl

对于 OS/2,只需在 *.cmd 文件中使用

extproc perl -S -your_switches

作为第一行(由于 cmd.exe 的“extproc”处理存在 bug,因此使用 -S)。对于 DOS,应该先创建一个相应的批处理文件,并在 ALTERNATE_SHEBANG 中对其进行编码(有关更多信息,请参阅源代码分发中的 dosish.h 文件)。

使用 ActiveState 的 Perl 端口时,Win95/NT 安装程序会修改注册表,将 .pl 扩展名与 Perl 解释器关联起来。如果你安装了另一个端口,甚至使用 Windows 端口的 gcc(例如,使用 cygwin 或 mingw32)从标准源代码构建自己的 Win95/NT Perl,那么你需要手动修改注册表。除了将 .pl 与解释器关联起来之外,NT 用户还可以使用:SET PATHEXT=%PATHEXT%;.PL,这样他们就可以通过键入 install-linux 来运行 install-linux.pl 程序。

在“经典”MacOS 中,Perl 程序将具有适当的创建者和类型,因此双击它们将调用 MacPerl 应用程序。在 Mac OS X 中,可以使用 Wil Sanchez 的 DropScript 实用程序从任何 #! 脚本创建可点击的应用程序:http://www.wsanchez.net/software/

重要!:无论你做什么,请不要感到沮丧,不要将 Perl 解释器直接放到你的 cgi-bin 目录中,以使你的程序在 Web 服务器上运行。这会带来极大的安全风险。花点时间弄清楚如何正确地做到这一点。

我可以在命令行上编写有用的 Perl 程序吗?

可以。阅读 perlrun 以获取更多信息。以下是一些示例。(这些示例假设标准的 Unix shell 引用规则。)

# sum first and last fields
perl -lane 'print $F[0] + $F[-1]' *

# identify text files
perl -le 'for(@ARGV) {print if -f && -T _}' *

# remove (most) comments from C program
perl -0777 -pe 's{/\*.*?\*/}{}gs' foo.c

# make file a month younger than today, defeating reaper daemons
perl -e '$X=24*60*60; utime(time(),time() + 30 * $X,@ARGV)' *

# find first unused uid
perl -le '$i++ while getpwuid($i); print $i'

# display reasonable manpath
echo $PATH | perl -nl -072 -e '
s![^/+]*$!man!&&-d&&!$s{$_}++&&push@m,$_;END{print"@m"}'

好吧,最后一个实际上是 Perl 混淆代码大赛的参赛作品。:-)

为什么我的 DOS/Mac/VMS 系统上无法使用 Perl 单行代码?

问题通常是这些系统上的命令解释器对引用的理解与创建单行代码的 Unix shell 不同。在某些系统上,你可能需要将单引号更改为双引号,但在 Unix 或 Plan9 系统上,你不能这样做。你可能还需要将单个 % 更改为 %%。

例如

# Unix (including Mac OS X)
perl -e 'print "Hello world\n"'

# DOS, etc.
perl -e "print \"Hello world\n\""

# Mac Classic
print "Hello world\n"
 (then Run "Myscript" or Shift-Command-R)

# MPW
perl -e 'print "Hello world\n"'

# VMS
perl -e "print ""Hello world\n"""

问题是这些示例都不可靠:它们依赖于命令解释器。在 Unix 下,前两个通常有效。在 DOS 下,很可能这两个都不起作用。如果 4DOS 是命令 shell,你可能会像这样获得更好的结果

perl -e "print <Ctrl-x>"Hello world\n<Ctrl-x>""

在 Mac 上,这取决于您使用的环境。MacPerl shell 或 MPW 与 Unix shell 在对多种引号变体的支持方面非常相似,只是它会自由使用 Mac 的非 ASCII 字符作为控制字符。

使用 qq()、q() 和 qx() 而不是 "双引号"、'单引号' 和 `反引号`,可以使单行代码更容易编写。

对于所有这些,没有通用的解决方案。这是一个混乱。

[此答案的部分内容由 Kenneth Albanowski 贡献。]

在哪里可以学习关于 CGI 或 Perl Web 编程的知识?

对于模块,请从 CPAN 获取 CGI 或 LWP 模块。对于教科书,请参阅关于书籍问题的两个专门针对 Web 内容的书籍。对于与 Web 相关的問題,例如“为什么我会收到 500 错误”或“为什么它在命令行上运行良好,但在浏览器中无法正常运行”,请参阅 perlfaq9 或 CGI MetaFAQ 中的故障排除指南和参考。

L<https://www.perl5.cn/CGI_MetaFAQ.html>

不过,强烈建议您研究 https://plackperl.org 和现代 Perl Web 框架;Perl 中的 Web 编程已经从简单的 CGI 脚本的旧时代发展了很长一段时间。

在哪里可以学习关于面向对象的 Perl 编程的知识?

一个好的起点是 perlootut,您可以使用 perlobj 作为参考。

关于 Perl 上的面向对象编程的优秀书籍是 Damian Conway 的 Manning Publications 的“面向对象的 Perl”,或 Randal Schwartz、brian d foy 和 Tom Phoenix 的 O'Reilly Media 的“中级 Perl”。

在哪里可以学习关于将 C 与 Perl 链接的知识?

如果您想从 Perl 调用 C,请从 perlxstut 开始,然后继续学习 perlxsxsubppperlguts。如果您想从 C 调用 Perl,请阅读 perlembedperlcallperlguts。不要忘记,您可以从查看现有扩展模块的作者如何编写代码并解决问题中学到很多东西。

您可能不需要 XS 的全部功能。Inline::C 模块允许您将 C 代码直接放入 Perl 源代码中。它处理所有使它工作的神奇功能。您仍然需要学习至少一些 perl API,但您不必处理 XS 支持文件的复杂性。

我已经阅读了 perlembed、perlguts 等文档,但我无法将 Perl 嵌入我的 C 程序中;我做错了什么?

从 CPAN 下载 ExtUtils::Embed 工具包并运行 `make test`。如果测试通过,请反复阅读这些文档。如果测试失败,请向 https://github.com/Perl/perl5/issues 提交错误报告,并附上 make test TEST_VERBOSE=1 的输出以及 perl -V 的结果。

当我尝试运行我的脚本时,我收到了这条消息。这是什么意思?

可以在 perldiag 中找到 Perl 错误消息和警告的完整列表,以及解释性文本。您也可以使用 splain 程序(随 Perl 一起分发)来解释错误消息

perl program 2>diag.out
splain [-v] [-p] diag.out

或者更改您的程序以解释这些消息。

use diagnostics;

use diagnostics -verbose;

什么是 MakeMaker?

(由 brian d foy 贡献)

The ExtUtils::MakeMaker 模块,通常简称为“MakeMaker”,将一个 Perl 脚本(通常称为 Makefile.PL)转换为一个 Makefile。Unix 工具 make 使用此文件来管理依赖项和操作,以处理和安装 Perl 发行版。

作者和版权

版权所有 (c) 1997-2010 Tom Christiansen、Nathan Torkington 和其他作者(如所述)。保留所有权利。

本文档是免费的;您可以在与 Perl 本身相同的条款下重新分发和/或修改它。

无论其分发方式如何,此处的所有代码示例均属于公有领域。您被允许并鼓励在您自己的程序中使用此代码及其任何衍生作品,无论出于娱乐目的还是盈利目的,您都可以随意使用。在代码中添加一个简单的注释以表彰 FAQ 将是礼貌的,但并非必需。