纲要十:包
TITLE
Synopsis 10: Packages
纲要 十:包
AUTHOR
Larry Wall <[email protected]>
VERSION
Maintainer: Larry WallDate: 27 Oct 2004 Last Modified: 20 Nov 2004 Number: 10 Version: 2
Overview / 概述
This synopsis summarizes Apocalypse 10, which discusses packages despite never having been written.
本纲要为启示录十的摘要,那份启示录讨论了从没写过的包。
Packages / 包
As in Perl 5, packages are the basis of modules and classes. Unlike in Perl 5, modules and classes are declared with separate keywords, but they're still just packages with extra behaviors.
与 Perl 5 中一样,包仍然是模块与类的基础。所不同的是,模块与类是用不同的 关键字声明。不过它们仍然只是带着额外操作的包。
An ordinary package is declared with the package
keyword. There are
two basic declaration syntaxes:
包一般是用关键字 package
来声明。这里有两种基本的声明语法:
package Foo; # rest of scope is in package Foo # 下面的作用域都在包 Foo 内 ...
package Bar {...} # block is in package Bar # 块在包 Bar 内
The first form, if it occurs as the first thing in a file, is taken to mean that the rest of the file is Perl 5 code. In any other place it just indicates a Perl 6 package (but maybe you should use a module instead).
第一种形式,如果它是一个文件的第一行,那就意味着整个文件都是 Perl 5 代码。 而在其他地方的话,那它只是说明这是个 Perl 6 包(但是或许你应该使用 module 来代替。
Since there are no barewords in Perl 6, package names must be predeclared,
or use the sigil-like ::PackageName
syntax. The ::
prefix does not
imply top-levelness as it does in Perl 5. (Use ::*
for that.)
因为 Perl 6 中将不允许出现 裸字/bareword, 所以包名必须得预先声明,否则你就得使用
类似 ::PackageName
这样的标记语法。与 Perl 5 不同,前缀 ::
不再意味着这是
最高阶。(我们使用 ::*
来代替。)
A bare package
declarator declares a global package name in ::*
.
To declare a package in the current package (or module, or class), use
our package
. To declare a lexically scoped package, use my package
.
Package names are always searched for from innermost scopes to outermost.
As with an initial ::
, the presence of a ::
within the name
does not imply globalness (unlike in Perl 5).
一个单独的 package
声明符是在 ::*
中声明一个全局包名。如果想在当前包(或模块
或类)中声明一个包,请使用 our package
. 如果想要声明一个词法作用域包,请使用
my package
. 包名总是总最近的作用域搜索到最外层作用域。以 ::
开头的名字并不
意味着这是全局的(这点与 Perl 5 不同)。
The ::*
namespace is not ``main''. The default namespace for the main
program is ::*Main
.
::*
命名空间不是 ``main''. 默认给主程序的命名空间为 ::*Main
.
Package traits are set using is
:
包的 traits 是用 is
来设定的:
package Foo is bar {...}
All symbolic links are done with the ::($expr)
syntax, which is
legal in any variable, package, module, or class name anywhere a
::Ident
is legal. The string returned by the expression will be
parsed for ::
indicating subpackage names. Do not confuse this
with the
所有的符号连接都是通过 C:<::($expr)> 语法来操作。只要是 ::Ident
合法的地方,
$expr 可以是变量,包,模块或类名。表达式返回的字符串默认在 ::
包内。
请不要与
%Foo::{$key}
syntax that lets you do a lookup in a particular symbol table. In this case,
the key is not parsed for ::
.
语法混淆,此语法会让你在一个特殊的符号表中做一查找。这种情况下, key 不是在
包 ::
内。
Autoloading / 自动加载
The package is the namespace that controls autoloading. There is still
an AUTOLOAD
hook that behaves as in Perl 5. However, that is being
replaced by various autoload hooks that distinguish declaration from
definition, and various types from one another. In particular:
包是用命名空间来控制自动加载的。你仍然可以像在 Perl 5 中一样使用 AUTOLOAD
hook. 但是在 Perl 6 中它被不同的自动加载 hooks 所替代。这些 hooks 通过定义
和各自不同的类型来区分声明。特别的:
AUTOSCALAR AUTOARRAY AUTOHASH AUTOSUB AUTOMETH
stand in for the declaration of objects; they are called when anyone
is searching for a name in the package (or module, or class), and the
name doesn't already exist in the package. (In particular, .can
calls AUTOMETH
when trying to determine if a class supports a
particular method.) The routines are expected to return a reference to
an object of the proper sort (i.e. a variable, subroutine, or method
reference), or undef if that name is not to be considered declared.
That object need not be defined yet, though the routine is allowed
to define it, and even install it into the symbol table if it likes.
代表对象的声明。当有人搜索包(或模块,或类)中一个不存在的名时,将调用它们。
(特别的,当查看一个类是否支持一个特定方法时,.can
将调用 AUTOMETH
.)
程序期待着返回一个特定类型的对象引用(如变量,子程序或方法的引用),或者如果
名字没有被声明则返回 undef. 只要程序允许定义对象,对象不需要被事先定义,
甚至只要你喜欢,将它加入符号表就可以了。
When someone tries to actually call or access an undefined object
(which may have come from one of the routines above, or might have
just been declared with a body of {...}
), a different set of hooks
is used to define actual behavior at the last moment:
当某人试图调用或获取一个未定义的对象(这可能来自上面的程序,或者只是在主体中
声明了 (...)
),一些不同的 hooks 会在在最后时刻被用以定义真实的操作:
AUTOSCALARDEF AUTOARRAYDEF AUTOHASHDEF AUTOSUBDEF AUTOMETHDEF
These routines are expected to define the object, but not to call
it, since the call is already ``scheduled'' from somewhere else.
(The goto &$AUTOLOAD
is implicit, in other words. But you can
hijack the call via the call
builtin, in which case the autoloader
behaves just like a wrapper--see A6.)
这些程序是被用来定义对象的,而不是调用它,因为调用已经在其他地方被“预定”了。
(换句话说,隐含调用了 go &$AUTOLOAD
。但是你可以通过内置的 call
来抢先调用,
这种情况下自动加载就类似于 wrapper —— 请参考 A6 。)
In any case, there is no longer any magical $AUTOLOAD
variable.
The name being declared or defined can be found in $_
instead. The name does not include the package name. You can always
get your own package name with $?PACKAGENAME
.
无论如何,你都不能使用 $AUTOLOAD
变量了。这个变量的定义和声明都将被 $_
替换。
这个变量不包含包名。你可以使用 $?PACKAGENAME
来获得你的包名。
blog comments powered by Disqus