Perl 简明教程

Perl - Packages and Modules

What are Packages?

package 语句将当前命名上下文切换到指定的命名空间(符号表)。因此 −

  1. 包是一个代码集合,它存在于其自己的命名空间中。

  2. 命名空间是一组唯一的变量名(也称为符号表)。

  3. 命名空间可以防止包之间的变量名冲突。

  4. 包使模块的构建成为可能,当使用模块时,不会影响模块自己的命名空间外部的变量和函数。

  5. 包持续有效,直到调用另一个包语句或当前块或文件的末尾。

  6. 您可以使用 :: 包限定符显式地引用包中的变量。

以下是文件中包含主包和 Foo 包的示例。此处已经使用特殊变量 PACKAGE 来打印包名。

#!/usr/bin/perl

# This is main package
$i = 1;
print "Package name : " , __PACKAGE__ , " $i\n";

package Foo;
# This is Foo package
$i = 10;
print "Package name : " , __PACKAGE__ , " $i\n";

package main;
# This is again main package
$i = 100;
print "Package name : " , __PACKAGE__ , " $i\n";
print "Package name : " , __PACKAGE__ ,  " $Foo::i\n";

1;

当以上代码执行后,它将产生以下结果 −

Package name : main 1
Package name : Foo 10
Package name : main 100
Package name : main 10

BEGIN and END Blocks

您可以定义任意数量的 BEGIN 和 END 命名代码块,它们分别充当构造函数和析构函数。

BEGIN { ... }
END { ... }
BEGIN { ... }
END { ... }
  1. 每次 BEGIN 块在 perl 脚本加载和编译后执行,但在执行任何其他语句之前执行。

  2. 每次 END 块在 perl 解释器退出之前执行。

  3. BEGIN 和 END 块在创建 Perl 模块时特别有用。

下面的示例演示了它的用法:

#!/usr/bin/perl

package Foo;
print "Begin and Block Demo\n";

BEGIN {
   print "This is BEGIN Block\n"
}

END {
   print "This is END Block\n"
}

1;

当以上代码执行后,它将产生以下结果 −

This is BEGIN Block
Begin and Block Demo
This is END Block

What are Perl Modules?

Perl 模块是定义在一个库文件中的可重用包,该文件的名称与包名称相同,但扩展名为 .pm。

名为 Foo.pm 的 Perl 模块文件可能包含如下语句。

#!/usr/bin/perl

package Foo;
sub bar {
   print "Hello $_[0]\n"
}

sub blat {
   print "World $_[0]\n"
}
1;

有关 Perl 模块的一些重要要点

  1. 函数 requireuse 将加载一个模块。

  2. 两者都使用 @INC 中的搜索路径列表来查找模块。

  3. requireuse 函数都调用 eval 函数来处理代码。

  4. 底部的 1; 使得 eval 计算为 TRUE(因此不会失败)。

The Require Function

可以通过调用 require 函数如下加载模块:

#!/usr/bin/perl

require Foo;

Foo::bar( "a" );
Foo::blat( "b" );
You must have noticed that the subroutine names must be fully qualified to call them. It would be nice to enable the subroutine bar and blat to be imported into our own namespace so we wouldn’t have to use the Foo

qualifier.

The Use Function

可以通过调用 use 函数加载模块。

#!/usr/bin/perl

use Foo;

bar( "a" );
blat( "b" );

注意,我们不必完全限定包的函数名称。 use 函数将从模块中导出一个符号列表,该列表给出了模块中添加的几个语句。

require Exporter;
@ISA = qw(Exporter);

然后,通过填充名为 @EXPORT 的列表变量,提供一个符号列表(标量、列表、哈希、子例程等):例如:

package Module;

require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(bar blat);

sub bar { print "Hello $_[0]\n" }
sub blat { print "World $_[0]\n" }
sub splat { print "Not $_[0]\n" }  # Not exported!

1;

Create the Perl Module Tree

当您准备发布您的 Perl 模块时,便有创建 Perl 模块树的标准方式。这是通过使用 h2xs 实用程序完成的。该实用程序随 Perl 一起提供。以下是如何使用 h2xs 的语法:

$h2xs -AX -n  ModuleName

例如,如果您的模块在 Person.pm 文件中,则只需发出以下命令:

$h2xs -AX -n Person

这会产生以下结果 −

Writing Person/lib/Person.pm
Writing Person/Makefile.PL
Writing Person/README
Writing Person/t/Person.t
Writing Person/Changes
Writing Person/MANIFEST

以下是这些选项的说明:

  1. -A 省略 Autoloader 代码(最好用于定义大量不常用的子例程的模块)。

  2. -X 省略 XS 元素(e Xternal Subroutine,其中 eXternal 表示 Perl 之外的,即 C)。

  3. -n 指定模块的名称。

因此,上述命令在 Person 目录中创建以下结构。实际结果如上所示。

  1. Changes

  2. Makefile.PL

  3. MANIFEST(包含程序包中所有文件列表)

  4. README

  5. t/ (test files)

  6. lib/(实际源代码在此处)

最后,您将 tar 此目录结构放入 Person.tar.gz 文件中,之后便可进行交付。您将需要使用适当的说明更新 README 文件。您还可以在 t 目录中提供一些测试示例文件。

Installing Perl Module

以 tar.gz 文件的形式下载 Perl 模块。使用以下序列安装已以 Person.tar.gz 文件形式下载的 Person.pm 任何 Perl 模块。

tar xvfz Person.tar.gz
cd Person
perl Makefile.PL
make
make install

Perl 解释器具有一个目录列表,用于搜索模块(全局数组 @INC)。