Manpages

NAME

perlfaq3 − 编 程 工 具 (2003/11/24 19:55:50)

DESCRIPTION 描 述

编 程 工 具 和 编 程 支 持

我 如 何 作 (任 何 事 )?

你 到 CPAN( 见 perlfaq2) 找 过 了 吗 ?也 许 别 人 已 经 写 了 某 个 模 组 可 以 解 决 你 的 问 题 。 你 查 过 相 关 的 说 明 文 件 了 吗 (man pages)?以 下 是 一 份 概 要 的 索 引 :

        基 础 Basics          perldata, perlvar, perlsyn, perlop, perlsub
        执 行 Execution       perlrun, perldebug
        函 数 Functions       perlfunc
        对 象 Objects         perlref, perlmod, perlobj, perltie
        数 据 结 构 Data Structures perlref, perllol, perldsc
        模 块 Modules         perlmod, perlmodlib, perlsub
        正 则 表 达 式 Regexes         perlre, perlfunc, perlop, perllocale
        移 植 Moving to perl5 perltrap, perl
        连 接 Linking w/C     perlxstut, perlxs, perlcall, perlguts, perlembed
        其 他 Various         http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz
                        (这 不 是 一 个 手 册 页 , 但 是 仍 然 很 有 用
                         是 有 关  Perl 技 术 的 大 量 技 巧 )

perltoc里 有 一 份 粗 略 的 perl 说 明 文 件 组 的 目 录

如 何 以 交 互 的 方 式 使 用 Perl?

典 型 的 作 法 是 使 用 perldebug(1)说 明 文 件 里 提 到 的 Perl 除 虫 器 , 在 一 个 「 空 的 」 ( 译 者 : 即 不 存 在 的 ) 程 式 上 执 行 , 像 这 样 :

    perl -de 42

接 下 来 所 打 入 的 任 意 合 法 Perl程 式 码 皆 会 立 刻 被 计 算 。 同 时 , 你 可 以 检 查 符 号 表 (symbol table)、 取 得 堆 叠 的 记 录 (stack backtraces)、 检 视 变 数 值 、 设 定 阻 断 点 (set breakpoints) 以 及 其 他 符 号 式 除 虫 器 (symbolic debuggers) 所 能 作 的 动 作 。

有 Perl shell吗 ?

The psh (Perl sh) is currently at version 1.8. The Perl Shell is a shell that combines the interactive nature of a Unix shell with the power of Perl. The goal is a full featured shell that behaves as expected for normal shell activity and uses Perl syntax and functionality for control-flow statements and other things. You can get psh at http://www.focusresearch.com/gregor/psh/ .

Zoidberg is a similar project and provides a shell written in perl, configured in perl and operated in perl. It is intended as a login shell and development environment. It can be found at http://zoidberg.sf.net/ or your local CPAN mirror.

The Shell.pm module (distributed with Perl) makes Perl try commands which aren’t part of the Perl language as shell commands. perlsh from the source distribution is simplistic and uninteresting, but may still be what you want.

怎 样 查 找 我 的 系 统 中 安 装 了 哪 些 模 块 ?

You can use the ExtUtils::Installed module to show all installed distributions, although it can take awhile to do its magic. The standard library which comes with Perl just shows up as "Perl" (although you can get those with Module::CoreList).

        use ExtUtils::Installed;

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

If you want a list of all of the Perl module filenames, you can use File::Find::Rule.

        use File::Find::Rule;

        my @files = File::Find::Rule->file()->name( ’*.pm’ )->in( @INC );

If you do not have that module, you can do the same thing with File::Find which is part of the standard library.

    use File::Find;
    my @files;
    find sub { push @files, $File::Find::name if -f _ && /\.pm$/ },
         @INC;
        print join "\n", @files;

If you simply need to quickly check to see if a module is available, you can check for its documentation. If you can read the documentation the module is most likely installed. If you cannot read the documentation, the module might not have any (in rare cases).

        prompt% perldoc Module::Name

You can also try to include the module in a one-liner to see if perl finds it.

        perl -MModule::Name -e1

如 何 替 我 的 Perl 程 式 除 虫 ?

你 用 过 "use warnings""−w" 吗 ? 它 们 启 用 警 告 模 式 , 来 检 测 不 确 定 的 代 码 。

你 用 过 "use strict" 吗 ? It prevents you from using symbolic references, makes you predeclare any subroutines that you call as bare words, and (probably most importantly) forces you to predeclare your variables with "my", "our", or "use vars".

Did you check the return values of each and every system call? The operating system (and thus Perl) tells you whether they worked, and if not why.

  open(FH, "> /etc/cantwrite")
    or die "Couldn’t write to /etc/cantwrite: $!\n";

Did you read perltrap? It’s full of gotchas for old and new Perl programmers and even has sections for those of you who are upgrading from languages like awk and C.

Have you tried the Perl debugger, described in perldebug? You can step through your program and see what it’s doing and thus work out why what it’s doing isn’t what it should be doing.

如 何 检 测 (profile) 我 的 perl 程 式 ?

你 该 自 CPAN抓 取 Devel::DProf 模 组 , 并 且 使 用 perl 标 准 套 件 所 附 的 Benchmark.pm。 Benchmark.pm让 你 测 量 程 式 码 的 某 部 份 在 执 行 上 所 花 的 时 间 , 而 Devel::DProf则 详 细 地 替 你 分 析 哪 一 部 份 的 程 式 用 掉 多 少 时 间 。

Here’s a sample use of Benchmark:

  use Benchmark;
  @junk = ’cat /etc/motd’;
  $count = 10_000;

  timethese($count, {
            ’map’ => sub { my @a = @junk;
                           map { s/a/b/ } @a;
                           return @a },
            ’for’ => sub { my @a = @junk;
                           for (@a) { s/a/b/ };
                           return @a },
           });

This is what it prints (on one machine--your results will be dependent on your hardware, operating system, and the load on your machine):

  Benchmark: timing 10000 iterations of for, map...
         for:  4 secs ( 3.97 usr  0.01 sys =  3.98 cpu)
         map:  6 secs ( 4.97 usr  0.00 sys =  4.97 cpu)

Be aware that a good benchmark is very hard to write. It only tests the data you give it and proves little about the differing complexities of contrasting algorithms.

如 何 替 我 的 Perl程 式 作 交 叉 参 考 ?

B::Xref模 组 可 以 替 你 的 Perl程 式 制 作 cross-reference报 告 。 用 法 是 :

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

有 Perl专 用 的 美 化 列 印 程 式 吗 ?

Perltidy is a Perl script which indents and reformats Perl scripts to make them easier to read by trying to follow the rules of the perlstyle. If you write Perl scripts, or spend much time reading them, you will probably find it useful. It is available at http://perltidy.sourceforge.net

Of course, if you simply follow the guidelines in perlstyle, you shouldn’t need to reformat. The habit of formatting your code as you write it will help prevent bugs. Your editor can and should help you with this. The perl-mode or newer cperl-mode for emacs can provide remarkable amounts of help with most (but not all) code, and even less programmable editors can provide significant assistance. Tom Christiansen and many other VI users swear by the following settings in vi and its clones:

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

Put that in your .exrc file (replacing the caret characters with control characters) and away you go. In insert mode, ^T is for indenting, ^D is for undenting, and ^O is for blockdenting-- as it were. A more complete example, with comments, can be found at http://www.cpan.org/authors/id/TOMC/scripts/toms.exrc.gz

The a2ps http://www−inf.enst.fr/%7Edemaille/a2ps/black+white.ps.gz does lots of things related to generating nicely printed output of documents, as does enscript at http://people.ssh.fi/mtr/genscript/ .

有 Perl的 ctags 吗 ?

Recent versions of ctags do much more than older versions did. EXUBERANT CTAGS is available from http://ctags.sourceforge.net/ and does a good job of making tags files for perl code.

There is also a simple one at http://www.cpan.org/authors/id/TOMC/scripts/ptags.gz which may do the trick. It can be easy to hack this into what you want.

Is there an IDE or Windows Perl Editor?

Perl programs are just plain text, so any editor will do.

If you’re on Unix, you already have an IDE--Unix itself. The UNIX philosophy is the philosophy of several small tools that each do one thing and do it well. It’s like a carpenter’s toolbox.

If you want an IDE , check the following:
Komodo

ActiveState’s cross-platform (as of April 2001 Windows and Linux), multi-language IDE has Perl support, including a regular expression debugger and remote debugging ( http://www.ActiveState.com/Products/Komodo/index.html ). (Visual Perl, a Visual Studio.NET plug-in is currently (early 2001) in beta ( http://www.ActiveState.com/Products/VisualPerl/index.html )).

The Object System

( http://www.castlelink.co.uk/object_system/ ) is a Perl web applications development IDE , apparently for any platform that runs Perl.

Open Perl IDE

( http://open−perl−ide.sourceforge.net/ ) Open Perl IDE is an integrated development environment for writing and debugging Perl scripts with ActiveState’s ActivePerl distribution under Windows 95/98/NT/2000.

PerlBuilder

( http://www.solutionsoft.com/perl.htm ) is an integrated development environment for Windows that supports Perl development.

visiPerl+

( http://helpconsulting.net/visiperl/ ) From Help Consulting, for Windows.

OptiPerl

( http://www.optiperl.com/ ) is a Windows IDE with simulated CGI environment, including debugger and syntax highlighting editor.

For editors: if you’re on Unix you probably have vi or a vi clone already, and possibly an emacs too, so you may not need to download anything. In any emacs the cperl-mode (M−x cperl−mode) gives you perhaps the best available Perl editing mode in any editor.

If you are using Windows, you can use any editor that lets you work with plain text, such as NotePad or WordPad. Word processors, such as Microsoft Word or WordPerfect, typically do not work since they insert all sorts of behind-the-scenes information, although some allow you to save files as "Text Only". You can also download text editors designed specifically for programming, such as Textpad ( http://www.textpad.com/ ) and UltraEdit ( http://www.ultraedit.com/ ), among others.

If you are using MacOS, the same concerns apply. MacPerl (for Classic environments) comes with a simple editor. Popular external editors are BBEdit ( http://www.bbedit.com/ ) or Alpha ( http://www.kelehers.org/alpha/ ). MacOS X users can use Unix editors as well.
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/

or a vi clone such as
Elvis

ftp://ftp.cs.pdx.edu/pub/elvis/ http://www.fh−wedel.de/elvis/

Vile

http://dickey.his.com/vile/vile.html

Vim

http://www.vim.org/

For vi lovers in general, Windows or elsewhere:

        http://www.thomer.com/thomer/vi/vi.html

nvi ( http://www.bostic.com/vi/ , available from CPAN in src/misc/) is yet another vi clone, unfortunately not available for Windows, but in UNIX platforms you might be interested in trying it out, firstly because strictly speaking it is not a vi clone, it is the real vi, or the new incarnation of it, and secondly because you can embed Perl inside it to use Perl as the scripting language. nvi is not alone in this, though: at least also vim and vile offer an embedded Perl.

The following are Win32 multilanguage editor/IDESs that support Perl:
Codewright

http://www.starbase.com/

MultiEdit

http://www.MultiEdit.com/

SlickEdit

http://www.slickedit.com/

There is also a toyedit Text widget based editor written in Perl that is distributed with the Tk module on CPAN . The ptkdb ( http://world.std.com/~aep/ptkdb/ ) is a Perl/tk based debugger that acts as a development environment of sorts. Perl Composer ( http://perlcomposer.sourceforge.net/ ) is an IDE for Perl/Tk GUI creation.

In addition to an editor/IDE you might be interested in a more powerful shell environment for Win32. Your options include
Bash

from the Cygwin package ( http://sources.redhat.com/cygwin/ )

Ksh

from the MKS Toolkit ( http://www.mks.com/ ), or the Bourne shell of the U/WIN environment ( http://www.research.att.com/sw/tools/uwin/ )

Tcsh

ftp://ftp.astron.com/pub/tcsh/ , see also http://www.primate.wisc.edu/software/csh−tcsh−book/

Zsh

ftp://ftp.blarg.net/users/amol/zsh/ , see also http://www.zsh.org/

MKS and U/WIN are commercial (U/WIN is free for educational and research purposes), Cygwin is covered by the GNU Public License (but that shouldn’t matter for Perl use). The Cygwin, MKS , and U/WIN all contain (in addition to the shells) a comprehensive set of standard UNIX toolkit utilities.

If you’re transferring text files between Unix and Windows using FTP be sure to transfer them in ASCII mode so the ends of lines are appropriately converted.

On Mac OS the MacPerl Application comes with a simple 32k text editor that behaves like a rudimentary IDE . In contrast to the MacPerl Application the MPW Perl tool can make use of the MPW Shell itself as an editor (with no 32k limit).
BBEdit and BBEdit Lite

are text editors for Mac OS that have a Perl sensitivity mode ( http://web.barebones.com/ ).

Alpha

is an editor, written and extensible in Tcl, that nonetheless has built in support for several popular markup and programming languages including Perl and HTML ( http://alpha.olm.net/ ).

Pepper and Pe are programming language sensitive text editors for Mac OS X and BeOS respectively ( http://www.hekkelman.com/ ).

哪 儿 有 vi 用 的 Perl 宏 ?

For a complete version of Tom Christiansen’s vi configuration file, see http://www.cpan.org/authors/Tom_Christiansen/scripts/toms.exrc.gz , the standard benchmark file for vi emulators. The file runs best with nvi, the current version of vi out of Berkeley, which incidentally can be built with an embedded Perl interpreter--see http://www.cpan.org/src/misc/ .

给 emacs用 的 perl模 式 又 要 去 哪 抓 呢 ?

从 大 约 Emacs 19.22版 (version 19 patchlevel 22)起 , 已 内 含 了 perl-mode.el及 perl 除 虫 器 的 支 援 。 它 们 应 该 会 和 标 准 的 Emacs 19版 一 起 出 货 。

在 perl原 始 码 的 目 录 下 , 你 会 找 到 一 个 叫 作 ’’emacs’’ 的 目 录 , 里 面 包 括 一 个 cperl-mode 可 以 把 程 式 中 的 关 键 字 上 色 、 提 供 内 文 相 关 的 协 助 以 及 其 它 方 便 的 功 能 。

注 意 : ’’main’foo’’( 其 中 的 单 引 号 ) 会 让 emacs的 perl-mode 出 问 题 , 并 且 会 弄 乱 内 缩 (indentation) 与 高 亮 (hilighting)。 不 过 你 本 来 就 该 用 ’’main::foo’’的 ( 译 者 按 : main’foo 是 表 示 模 组 或 package的 旧 式 写 法 ; 新 式 的 [perl5的 ]写 法 是 main::foo) 。

如 何 在 Perl里 使 用 curses?

The Curses module from CPAN provides a dynamically loadable object module interface to a curses library. A small demo can be found at the directory http://www.cpan.org/authors/Tom_Christiansen/scripts/rep.gz ; this program repeats a command and updates the screen as needed, rendering rep ps axu similar to top.

X或 Tk如 何 与 Perl配 合 呢 ?

Tk 模 块 是 一 个 完 全 以 Perl 为 基 础 , 面 向 对 象 的 接 口 , 让 你 不 用 学 Tcl也 可 以 使 用 Tk工 具 组 。 Sx则 是 Athena Widget set专 用 的 介 面 。 两 者 都 可 在 CPAN取 得 。 参 见 分 类 http://www.cpan.org/modules/by−category/08_User_Interfaces/

Invaluable for Perl/Tk programming are the Perl/Tk FAQ at http://w4.lns.cornell.edu/%7Epvhp/ptk/ptkTOC.html , the Perl/Tk Reference Guide available at http://www.cpan.org/authors/Stephen_O_Lidie/ , and the online manpages at http://www−users.cs.umn.edu/%7Eamundson/perl/perltk/toc.html .

如 何 不 靠 CGI或 Tk 帮 助 作 出 简 单 的 目 录 ( 选 单 ) ?

http://www.cpan.org/authors/id/SKUNZ/perlmenu.v4.0.tar.gz 是 个 以 curses为 基 础 的 模 组 , 可 以 达 成 你 的 要 求 。

如 何 让 我 的 Perl程 式 跑 得 更 快 些 ?

最 好 是 能 设 计 一 个 较 好 的 演 算 法 (algorithm), 这 通 常 会 让 程 式 有 大 不 相 同 的 表 现 。 Jon Bentley’s book Programming Pearls (没 有 拼 写 错 误 !) 中 有 些 你 或 许 想 知 道 的 增 进 效 率 小 技 巧 。 Advice on benchmarking boils down to: benchmark and profile to make sure you’re optimizing the right part, look for better algorithms instead of microtuning your code, and when all else fails consider just buying faster hardware. You will probably want to read the answer to the earlier question ’’How do I profile my Perl programs?’’ if you haven’t done so already.

其 它 方 法 包 括 自 动 载 入 较 少 使 用 的 Perl 程 式 码 。 请 参 看 标 准 perl 套 件 中 的 AutoSplit及 AutoLoader模 组 的 用 法 。 或 当 你 能 断 定 程 式 执 行 效 率 的 瓶 颈 在 何 处 时 , 用 C来 写 那 个 部 份 , 就 像 用 组 合 语 言 来 撰 写 C程 式 的 瓶 颈 部 份 一 样 。 与 此 法 相 近 的 是 使 用 以 C撰 写 瓶 颈 部 份 的 模 组 (例 如 CPAN中 的 PDL 模 组 )。

如 果 你 目 前 是 将 你 的 perl直 译 器 动 态 连 结 到 libc.so的 话 , 重 新 作 一 份 静 态 连 结 到 libc.a的 perl直 译 器 可 以 提 高 10-25%的 执 行 效 能 。 虽 然 这 会 使 你 的 perl直 译 器 变 得 更 胖 , 但 你 的 Perl程 式 (及 程 式 设 计 者 ) 或 许 会 因 此 而 感 谢 你 。 详 情 请 参 考 perl标 准 套 件 原 始 码 版 本 中 的 INSTALL 档 案 。

使 用 undump程 式 把 编 译 後 的 档 案 格 式 存 到 硬 碟 里 以 加 快 执 行 的 速 度 已 经 是 老 掉 牙 的 手 法 了 。 它 已 不 再 是 个 可 行 的 方 法 , 因 为 这 方 法 只 有 几 种 平 台 能 用 , 况 且 它 终 究 不 是 个 治 本 之 道 。

如 何 让 我 的 Perl 程 序 少 用 一 些 内 存 ?

当 问 题 变 成 时 间 与 空 间 的 交 易 时 , Perl 几 乎 总 是 用 记 忆 体 来 帮 忙 解 决 问 题 。 Perl中 的 纯 量 (Scalar) 耗 掉 的 记 忆 体 比 C中 的 字 串 形 态 还 多 , 阵 列 又 更 多 , 更 别 谈 杂 凑 阵 列 了 (Hashes)。 关 於 这 一 点 , 我 们 当 然 还 有 很 多 工 作 得 作 , 近 来 发 布 的 版 本 , 已 开 始 针 对 这 些 问 题 做 改 进 了 。 例 如 , 5.004 版 中 , 重 复 的 散 列 键 (duplicate hash keys) 由 使 用 它 的 杂 凑 阵 列 共 用 , 这 样 就 不 用 再 重 新 定 份 位 置 给 它 了 。

在 某 些 情 况 下 , 使 用 substr()或 vec()来 模 拟 数 组 有 很 大 的 好 处 。 例 如 , 一 个 有 上 千 个 布 林 代 数 值 的 阵 列 将 占 用 至 少 20,000位 元 组 的 空 间 , 但 是 它 可 以 被 转 变 为 一 个 125位 元 组 的 位 元 向 量 (bit vector)以 节 省 相 当 可 观 的 记 忆 体 。 标 准 套 件 中 的 Tie::SubstrHash模 组 也 能 够 帮 助 特 定 形 态 的 资 料 结 构 节 省 些 记 忆 体 。 若 你 正 在 和 一 些 特 殊 的 资 料 结 构 奋 战 (例 如 , 矩 阵 ), 用 C写 的 模 组 所 耗 掉 的 记 忆 体 可 能 低 於 同 功 能 并 用 Perl写 的 模 组 。

另 一 件 值 得 一 试 的 是 , 查 一 下 你 的 Perl是 以 系 统 内 的 malloc 还 是 Perl内 含 的 malloc 编 译 起 来 的 。 不 论 是 哪 个 , 试 着 换 成 另 一 个 , 再 看 看 这 是 否 造 成 任 何 差 别 。 关 於 malloc的 资 讯 可 在 perl标 准 套 件 原 始 码 版 中 的 INSTALL 档 案 找 到 。 键 入 "perl −V:usemymalloc". 就 可 以 知 道 你 是 否 在 使 用 perl的 malloc。

Of course, the best way to save memory is to not do anything to waste it in the first place. Good programming practices can go a long way toward this:
* Don’t slurp!

Don’t read an entire file into memory if you can process it line by line. Or more concretely, use a loop like this:

        #
        # Good Idea
        #
        while (<FILE>) {
           # ...
        }

instead of this:

        #
        # Bad Idea
        #
        @data = <FILE>;
        foreach (@data) {
            # ...
        }

When the files you’re processing are small, it doesn’t much matter which way you do it, but it makes a huge difference when they start getting larger.

* Use map and grep selectively

Remember that both map and grep expect a LIST argument, so doing this:

        @wanted = grep {/pattern/} <FILE>;

will cause the entire file to be slurped. For large files, it’s better to loop:

        while (<FILE>) {
                push(@wanted, $_) if /pattern/;
        }

* Avoid unnecessary quotes and stringification

Don’t quote large strings unless absolutely necessary:

        my $copy = "$large_string";

makes 2 copies of $large_string (one for $copy and another for the quotes), whereas

        my $copy = $large_string;

only makes one copy.

Ditto for stringifying large arrays:

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

is much more memory-efficient than either

        print join "\n", @big_array;

or

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

* Pass by reference

Pass arrays and hashes by reference, not by value. For one thing, it’s the only way to pass multiple lists or hashes (or both) in a single call/return. It also avoids creating a copy of all the contents. This requires some judgment, however, because any changes will be propagated back to the original data. If you really want to mangle (er, modify) a copy, you’ll have to sacrifice the memory needed to make one.

* Tie large variables to disk.

For "big" data stores (i.e. ones that exceed available memory) consider using one of the DB modules to store it on disk instead of in RAM . This will incur a penalty in access time, but that’s probably better than causing your hard disk to thrash due to massive swapping.

把 局 部 变 量 的 引 用 返 回 是 不 安 全 的 做 法 吗 ?

这 样 是 安 全 的 , Perl的 资 源 回 收 (garbage collection)系 统 会 解 决 此 问 题 。

    sub makeone {
        my @a = ( 1 .. 10 );
        return \@a;
    }
    for ( 1 .. 10 ) {
        push @many, makeone();
    }
    print $many[4][5], "\n";
    print "@many\n";

我 如 何 释 放 一 个 数 组 或 散 列 以 缩 小 我 的 程 式 尺 寸 ?

你 无 法 这 麽 作 。 系 统 配 置 给 程 式 的 记 忆 体 是 覆 水 难 收 。 这 也 是 为 何 执 行 很 长 一 段 时 间 的 程 式 有 时 会 重 新 执 行 (re-exec)它 们 自 己 的 原 因 。 Some operating systems (notably, systems that use mmap(2) for allocating large chunks of memory) can reclaim memory that is no longer used, but on such systems, perl must be configured and compiled to use the OS ’s malloc, not perl’s.

然 而 , 在 使 用 你 的 变 数 时 , 明 智 地 用 my()来 定 义 执 行 范 围 , 可 让 Perl在 脱 离 该 范 围 後 将 它 们 所 占 的 空 间 释 放 给 其 它 部 份 的 程 式 。 (注 : my()的 变 数 也 比 全 域 变 数 执 行 起 来 快 10%。 )当 然 , 一 个 全 域 变 数 永 远 没 有 超 出 范 围 的 时 候 , 所 以 你 无 法 将 它 占 用 的 空 间 自 动 重 新 分 配 , 不 过 , 把 它 undef() 或 / 和 delete()会 有 相 同 的 效 果 。 总 之 , 在 Perl里 , 你 并 不 能 / 应 该 去 担 心 太 多 有 关 记 忆 体 定 址 与 解 除 这 件 事 , 而 我 们 连 添 加 这 项 功 能 ( 资 料 形 态 的 预 先 定 址 ) , 目 前 都 已 在 进 行 中 。

如 何 让 我 的 CGI脚 本 (script)执 行 起 来 更 有 效 率 ?

除 了 使 一 般 Perl程 式 加 快 或 缩 小 的 平 常 手 段 外 , 一 个 CGI 程 式 还 有 其 他 的 顾 虑 。 也 许 它 每 秒 会 被 执 行 好 几 次 。 每 次 它 执 行 时 , 重 新 编 译 所 花 的 时 间 、 加 上 定 址 所 需 的 1 MB以 上 的 系 统 记 忆 体 , 就 是 一 个 大 杀 手 。 光 是 编 译 成 C 是 没 啥 帮 助 的 , 因 为 瓶 颈 在 於 整 个 程 序 开 始 时 所 负 担 的 包 袱 (start-up overhead) 。

最 起 码 有 两 种 较 流 行 的 方 法 可 以 避 免 这 些 包 袱 。 一 种 解 法 是 将 mod_perl 或 是 mod_fastcgi其 中 一 个 模 组 加 在 你 所 执 行 的 Apache HTTP server。

有 了 mod_perl 和 Apache::*模 组 (从 CPAN取 得 ), httpd执 行 时 会 带 起 一 个 内 嵌 的 Perl直 译 器 , 而 它 会 预 先 编 译 你 的 程 式 , 并 在 不 产 生 其 它 子 程 序 的 情 况 下 用 同 一 个 定 址 空 间 来 执 行 。 Apache 扩 充 模 组 亦 给 Perl一 个 连 通 server API 的 管 道 , 所 以 用 Perl写 的 模 组 可 以 做 到 任 何 C写 的 模 组 所 具 备 的 功 能 。 详 情 请 参 阅 http://perl.apache.org/

而 有 了 FCGI模 组 (自 CPAN取 得 ) 和 mod_fastcgi 模 块 (从 http://www.fastcgi.com/取; 得 ), 每 个 Perl 程 序 将 成 为 一 个 永 久 的 CGI 守 护 进 程 。

这 些 方 法 对 你 的 系 统 与 你 撰 写 CGI程 式 的 方 法 都 有 超 乎 想 像 之 外 的 影 响 , 所 以 请 小 心 地 使 用 它 们 。

参 见 http://www.cpan.org/modules/by−category/15_World_Wide_Web_HTML_HTTP_CGI/ .

A non−free, commercial product, ’’The Velocity Engine for Perl’’, (http://www.binevolve.com/ or http://www.binevolve.com/velocigen/ ) might also be worth looking at. It will allow you to increase the performance of your Perl programs, running programs up to 25 times faster than normal CGI Perl when running in persistent Perl mode or 4 to 5 times faster without any modification to your existing CGI programs. Fully functional evaluation copies are available from the web site.

如 何 隐 藏 Perl程 式 的 原 始 码 ?

删 除 它 。 :-) 说 真 的 , 有 一 些 具 有 不 同 “安 全 ”等 级 的 方 法 (大 部 分 都 不 能 令 人 满 意 )。

首 先 , 你 不 能 拿 走 读 取 权 , 不 然 你 的 程 式 怎 麽 被 解 译 或 是 编 译 呢 ? (不 过 那 也 并 不 表 示 一 个 CGI程 式 的 原 始 码 可 以 被 使 用 者 读 取 。 )所 以 你 得 让 档 案 权 限 停 留 在 0755这 个 友 善 的 阶 段 。

有 些 人 认 为 这 是 个 安 全 上 的 漏 洞 。 不 过 若 你 的 程 式 作 的 是 不 安 全 的 事 情 , 光 仰 赖 别 人 看 不 见 这 些 漏 洞 、 不 知 从 何 下 手 , 那 麽 它 依 然 是 不 安 全 的 。 其 实 对 有 些 人 来 说 他 们 并 不 需 要 看 见 程 式 原 始 码 便 可 能 判 定 并 揭 露 这 些 不 安 全 的 部 份 。 透 过 隐 瞒 达 到 的 安 全 , 就 是 不 修 正 臭 虫 反 而 隐 藏 它 们 , 实 际 上 是 没 有 安 全 性 可 言 的 。

你 可 以 试 着 透 过 原 始 码 过 滤 模 组 (CPAN中 的 Filter::*)来 替 原 始 码 加 密 。 但 高 手 也 许 有 办 法 将 其 解 密 还 原 。 你 也 可 以 用 下 面 提 到 的 byte code 编 译 器 与 直 译 器 , 但 高 手 也 有 可 能 反 解 译 它 。 你 可 以 试 试 後 面 提 到 的 原 生 码 编 译 器 (native-code compiler), 但 高 手 也 有 可 能 反 组 译 它 。 这 些 手 段 都 需 要 不 同 难 度 的 技 巧 才 能 让 别 人 拿 到 你 的 原 始 码 , 但 没 有 一 种 能 够 很 确 定 地 隐 藏 它 。 (这 对 每 种 语 言 来 说 都 为 真 , 不 是 只 有 Perl)

很 容 易 从 Perl 程 序 中 恢 复 出 源 码 。 只 要 将 程 序 作 为 perl 解 释 器 的 参 数 , 并 且 使 用 B:: 中 的 模 块 就 可 以 了 。 B::Deparse 模 块 足 以 恢 复 大 多 数 隐 藏 的 代 码 。 再 次 的 , 这 不 是 Perl 特 有 的 东 西 。

如 果 你 所 担 心 的 是 别 人 自 你 的 程 式 码 中 获 利 , 那 麽 一 纸 权 限 执 照 是 能 提 供 你 法 律 上 安 全 的 唯 一 途 径 。 注 册 你 的 软 体 并 且 写 份 权 限 说 明 , 再 加 上 一 些 具 威 胁 性 的 句 子 像 “这 是 XYZ公 司 未 出 版 的 专 有 软 体 。 你 能 撷 取 它 并 不 代 表 你 具 有 使 用 的 权 限 ...”之 类 云 云 。 当 然 , 我 们 不 是 律 师 , 所 以 若 你 想 要 你 的 执 照 中 每 一 句 话 在 法 庭 上 都 站 得 住 脚 , 就 去 见 个 律 师 吧 。

如 何 把 我 的 Perl程 式 码 编 译 成 byte code或 C?

Malcolm Beattie已 经 写 了 一 个 多 功 能 的 後 端 编 译 器 , 可 以 从 CPAN取 得 , 它 就 能 做 到 这 两 项 功 能 。 它 包 含 在 perl5.005 发 布 中 , 但 是 仍 然 是 测 试 版 。 这 代 表 着 若 你 是 个 程 式 设 计 员 而 非 寻 找 万 灵 解 药 的 人 , 那 麽 参 与 其 测 试 就 会 充 满 趣 味 。

请 了 解 光 是 编 译 成 C 其 本 身 或 在 本 质 上 并 不 能 保 证 它 就 会 跑 得 快 更 多 。 那 是 因 为 除 了 在 运 气 好 的 状 况 中 有 一 堆 可 以 衍 生 成 出 来 的 原 生 形 态 外 , 平 时 的 Perl 执 行 系 统 环 境 依 然 存 在 因 此 依 然 会 花 差 不 多 长 的 执 行 时 间 与 占 用 差 不 多 大 小 的 记 忆 空 间 。 大 多 数 程 式 能 省 下 来 的 不 过 是 编 译 时 间 , 这 使 执 行 速 度 顶 多 快 10-30%。 有 些 罕 见 的 程 式 能 真 正 从 中 受 利 (例 如 增 快 好 几 倍 ), 但 这 还 得 配 合 原 始 码 的 微 调 。

你 或 许 会 惊 讶 地 发 现 , 现 行 版 本 的 编 译 器 做 出 来 的 执 行 档 大 小 跟 你 的 Perl直 译 器 一 样 大 , 有 时 更 大 些 。 那 是 因 为 依 照 现 在 的 写 法 , 所 有 的 程 式 皆 转 成 一 个 被 eval()的 大 叙 述 。 只 要 建 造 一 个 动 态 连 结 的 libperl.so程 式 库 , 并 将 之 连 结 起 来 , 你 就 可 以 戏 剧 性 地 减 少 这 种 浪 费 。 参 看 perl原 始 码 套 件 中 的 INSTALL pod档 案 以 获 得 更 详 尽 的 讯 息 。 如 果 你 用 这 方 法 连 结 你 主 要 的 perl执 行 档 , 就 能 使 它 变 得 很 渺 小 。 举 例 来 说 , 在 作 者 之 一 的 系 统 里 , /usr/bin/perl只 有 11k“小 ”而 已 !

In general, the compiler will do nothing to make a Perl program smaller, faster, more portable, or more secure. In fact, it can make your situation worse. The executable will be bigger, your VM system may take longer to load the whole thing, the binary is fragile and hard to fix, and compilation never stopped software piracy in the form of crackers, viruses, or bootleggers. The real advantage of the compiler is merely packaging, and once you see the size of what it makes (well, unless you use a shared libperl.so), you’ll probably want a complete Perl install anyway.

How can I compile Perl into Java?

You can also integrate Java and Perl with the Perl Resource Kit from O’Reilly and Associates. See http://www.oreilly.com/catalog/prkunix/ .

Perl 5.6 comes with Java Perl Lingo, or JPL . JPL , still in development, allows Perl code to be called from Java. See jpl/README in the Perl source tree.

如 何 才 能 让

OS/2下 只 要 用 :

    extproc perl -S -your_switches

当 作 "*.cmd" 档 案 的 第 一 行 ("−S" 是 因 cmd.exe中 其 ’extproc’处 理 的 臭 虫 才 要 的 )。 DOS使 用 者 应 先 制 作 一 个 相 对 的 batch 档 案 然 後 将 它 以 ALTERNATIVE_SHEBANG 的 方 式 写 成 程 式 。 (更 多 讯 息 在 原 始 码 版 本 的 INSTALL档 案 里 )

The Win95/NT installation, when using the ActiveState port of Perl, will modify the Registry to associate the ".pl" extension with the perl interpreter. If you install another port, perhaps even building your own Win95/NT Perl from the standard sources by using a Windows port of gcc (e.g., with cygwin or mingw32), then you’ll have to modify the Registry yourself. In addition to associating ".pl" with the interpreter, NT people can use: "SET PATHEXT=%PATHEXT%;.PL" to let them run the program "install−linux.pl" merely by typing "install−linux".

麦 金 塔 的 perl程 式 将 会 有 适 当 的 创 造 者 与 形 态 (Creator and Type), 所 以 双 击 它 们 就 会 执 行 这 些 perl 应 用 程 式 。

重 要 :不 论 你 做 什 麽 , 请 千 万 不 要 因 为 觉 得 沮 丧 , 就 把 perl 直 译 器 丢 到 你 的 cgi-bin目 录 下 , 好 让 你 的 web 伺 服 器 能 执 行 你 的 程 式 。 这 是 一 个 非 常 大 的 安 全 漏 洞 。 花 点 时 间 想 想 怎 样 才 是 正 确 的 做 法 吧 。

我 能 利 用 命 令 行 写 出 有 用 的 程 式 吗 ?

可 以 。 详 情 请 看 perlrun。 以 下 有 些 范 例 (假 设 用 的 是 标 准 的 Unix shell引 言 规 则 )。

    # 把 第 一 栏 和 最 後 一 栏 相 加
    perl -lane ’print $F[0] + $F[-1]’ *
    # 辨 别 是 否 为 文 字 档
    perl -le ’for(@ARGV) {print if -f && -T _}’ *
    # 移 除  C程 式 中 的 说 明
    perl -0777 -pe ’s{/\*.*?\*/}{}gs’ foo.c
    # 让 档 案 年 轻 一 个 月 , 躲 避  reaper daemons
    perl -e ’$X=24*60*60; utime(time(),time() + 30 * $X,@ARGV)’ *
    # 找 出 第 一 个 未 用 的  uid
    perl -le ’$i++ while getpwuid($i); print $i’

    # 显 示 合 理 的 使 用 说 明 路 径  (manpath)
    echo $PATH ⎪ perl -nl -072 -e ’
        s![^/+]*$!man!&&-d&&!$s{$_}++&&push@m,$_;END{print"@m"}’

好 吧 , 最 後 一 个 例 子 事 实 上 是 「 perl程 式 困 惑 化 」 竞 赛 (Obfuscated Perl)的 参 赛 作 品 。 :-)

为 何 一 行 的 perl 程 式 无 法 在 我 的 DOS/Mac/VMS系 统 上 运 作 ?

问 题 通 常 出 在 那 些 系 统 的 命 令 解 译 器 对 於 参 数 的 引 用 与 Unix shells 所 作 的 解 释 不 同 , 而 後 者 很 不 幸 的 是 这 些 一 行 perl 的 生 父 。 在 某 些 系 统 , 也 许 你 得 把 单 引 号 改 成 双 引 号 , 但 这 却 是 你 万 万 不 可 在 Unix或 Plan9系 统 上 作 的 事 。 你 也 许 还 得 把 一 个 %改 成 %%。

例 如 :

    # Unix
    perl -e ’print "Hello world\n"’
    # DOS 和 其 他 机 器
    perl -e "print \"Hello world\n\""
    # Mac
    print "Hello world\n"
     (然 后 运 行  "Myscript" 或 按  Shift-Command-R)
    # MPW
    perl -e ’print "Hello world\n"’

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

问 题 是 , 这 些 方 法 没 有 一 个 是 完 全 可 靠 的 : 它 都 得 看 命 令 解 译 器 的 脸 色 。 在 Unix中 , 前 两 者 通 常 可 以 用 。 在 DOS下 , 两 者 可 能 都 没 有 用 。 若 4DOS是 命 令 解 译 器 , 下 面 此 法 可 能 比 较 有 希 望 :

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

在 Mac 下 , 端 视 你 所 用 的 环 境 为 何 。 MacPerl所 附 的 shell, 或 是 MPW, 其 所 支 援 的 参 数 格 式 有 不 少 都 蛮 像 Unix shells的 , 除 了 它 自 在 地 使 用 Mac 的 非 ASCII字 元 当 成 控 制 字 元 。

Using qq(), q(), and qx(), instead of "double quotes", ’single quotes’, and ’backticks’, may make one-liners easier to write.

恐 怕 我 得 说 这 问 题 并 没 有 一 般 解 。 白 话 一 点 说 , 它 真 是 一 团 乱 。

[部 份 答 案 是 由 Kenneth Albanowski 所 提 供 的 。 ]

我 得 去 哪 里 学 Perl的 CGI或 是 Web程 式 设 计 呢 ?

就 模 组 来 说 , 去 CPAN抓 CGI 和 LWP 两 个 模 组 。 就 书 本 来 看 , 参 考 关 於 书 那 部 份 里 特 别 和 web 相 关 的 问 题 。 若 有 与 web相 关 的 疑 难 杂 症 , 像 “为 何 我 收 到 500错 误 ”或 “它 在 命 令 列 模 式 下 跑 得 好 好 的 , 怎 麽 不 能 在 浏 览 器 下 正 常 执 行 ”时 , 请 参 看 :

        http://www.perl.org/CGI_MetaFAQ.html

从 哪 里 可 以 学 习 面 向 对 象 的 Perl 编 程 ?

perltoot是 个 好 开 始 , 然 後 你 可 以 再 参 考 perlobj 和 perlboot, Perltoot, perltooc 以 及 perlbot (如 果 你 使 用 老 版 本 的 Perl, 你 可 能 没 有 这 些 。 去 http://www.perldoc.com/ 下 载 吧 , 但 是 首 先 考 虑 一 下 升 级 你 的 perl)

有 本 好 书 关 于 Perl 中 的 OO 是 "Object−Oriented Perl" 作 者 是 Damian Conway , 出 版 社 为 Manning Publications, http://www.manning.com/Conway/index.html

从 哪 里 可 以 学 习 将 Perl 与 C 连 接 ? [h2xs, xsubpp]

若 你 要 从 Perl程 式 呼 叫 C, 就 自 perlxstut开 始 向 perlxs , xsubpp , 及 perlguts前 进 。 反 之 , 则 读 perlembed , perlcall , 及 perlguts 。 别 忘 了 你 可 以 从 各 模 组 的 作 者 如 何 写 他 们 的 模 组 及 解 决 他 们 的 问 题 中 学 到 很 多 。

我 已 经 阅 读 了 perlembed,perlguts 等 等 , 但 是 还 是 不 能 在 我 的 C 程 序 中 嵌 入 perl; 我 作 错 了 什 么 ?

自 CPAN 下 载 ExtUtils::Embed 套 件 , 然 後 执 行 ’make test’。 如 果 测 试 成 功 , 就 一 遍 又 一 遍 地 读 那 些 pod 说 明 档 案 。 若 它 失 败 了 , 参 看 perlbug并 送 一 份 内 有 "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;

什 麽 是 What’s MakeMaker?

此 模 组 (亦 为 标 准 perl 套 件 之 一 部 份 )设 计 的 目 的 是 要 替 一 个 模 组 从 一 个 Makefile.PL 中 自 动 撰 写 出 一 个 Makefile。 详 情 请 看 ExtUtils::MakeMaker。

AUTHOR AND COPYRIGHT

Copyright (c) 1997−2002 Tom Christiansen and Nathan Torkington. All rights reserved.

This documentation is free; you can redistribute it and/or modify it under the same terms as Perl itself.

Irrespective of its distribution, all code examples here are in the public domain. You are permitted and encouraged to use this code and any derivatives thereof in your own programs for fun or for profit as you see fit. A simple comment in the code giving credit to the FAQ would be courteous but is not required.

译 者

陈 彦 铭 , 萧 百 龄 , 两 只 老 虎 工 作 室