Perl 中的 名称空间 是一种机制,它将若干具名实体关联并封装于某具名分类之下。它就 像你的姓或是某种品牌,只能反映出命名归类上的关系而非其他。(这类关系可以存在,但不 是必须的。)
Perl 5 中的 包 是单一名称空间下代码的集合。在某种意义上,包和名称空间是等价的; 包代表源代码而名称空间代表当 Perl 分析这段代码时创建的实体。这是个微妙的区别
package
关键字声明一个包和一个名称空间:
所有在包声明语句之后的对全局变量和函数的声明或引用,都指向位于 MyCode
名称空间 内的符号。如果代码是这样写的,那么你只能通过 完全限定 名称────@MyCode::boxes
────来从 main
名称空间访问 @boxes
变量。相似地,你仅可以通过 MyCode::add_box()
来调用 add_box()
函数。一个完全限定名称包括了完整包名。
默认包是 main
包。如果你不明确声明一个包,无论是在命令行 one-liner 或在独立的 Perl 程序甚至是磁盘上的 .pm 文件,那么当前包就是 main
包。
除包名(main
或是 MyCode
或其他任何允许的标识符)外,一个包还拥有一个版本以及 三个隐含的方法,分别是 VERSION()
、import()
(importing)和 unimport()
。 VERSION()
返回一个包的版本。
包版本是包含在名为 $VERSION
的包全局变量中的一系列数字。按照惯例,版本号倾向于写 成一系列由点分隔整数的形式,例如 1.23
和 1.1.10
,其中每一段是一个整数,但通常 就这样写。
Perl 5.12 引入了一种简化版本号的新语法。如果你编写的代码不会在早先版本的 Perl 5 上 运行,你可以避免不少不必要的复杂性:
在 5.10 以及早期的版本中,声明包版本最简单的方式是:
每个包都有 VERSION()
方法;它们继承自 UNIVERSAL
基类。它返回 $VERSION
中 的值。虽然没有什么理由这样做,但你还是可以按需重写此方法。使用 VERSION()
方法 是获取一个包版本号最简便的办法:
每一句 package
声明都会使 Perl 完成两件任务。如果名称空间不存在则创建它。 它还告诉语法分析器将后续的包全局符号(全局变量和函数)放入该名称空间下。
Perl 有 开放式名称空间。通过使用包声明语句,你在任何时候向一个名称空间添 加函数和变量:
……或者在声明时使用完全限定的函数名称:
Perl 5 是那么的开放以至于你可以在编译期、运行时的任何时刻或从其他文件向其中 添加内容。当然,这样做使人迷惑,因此应尽量避免。
名称空间可以按组织需要分为多个级别。这并不意味着继承关系,包与包之间也没有什 么技术上的联系────仅对于这段代码的 阅读者 来说有语义上的关系罢了。
常见的做法是为业务或项目创建一个顶层名称空间。这对于阅读代码和发现组件间关系 来说变得方便,同时也为代码和包在磁盘上的组织提供便利。因此:
StrangeMonkey
是项目名称;StrangeMonkey::UI
包含顶层用户接口的代码;StrangeMonkey::Persistence
包含顶层数据管理代码;StrangeMonkey::Test
包含为项目编写的顶层测试代码;
……等等。
Hey! The above document had some coding errors, which are explained below:
- Around line 5:
-
A non-empty Z<>
- Around line 13:
-
Deleting unknown formatting code N<>