12 March 2005
This post may be outdated due to it was written on 2005. The links may be broken. The code may be not working anymore. Leave comments if needed.
English version: http://dev.perl.org/perl6/synopsis/S10.html

TITLE

Synopsis 10: Packages

纲要 十:包

AUTHOR

Larry Wall <[email protected]>

VERSION

  Maintainer: Larry Wall 
  Date: 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