14 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/S11.html


Synopsis 11: Modules

纲要 十一:模块


Larry Wall <[email protected]>


  Maintainer: Larry Wall 
  Date: 27 Oct 2004
  Last Modified: 2 Dec 2004
  Number: 11
  Version: 4

Overview 概述

This synopsis discusses those portions of Apocalypse 12 that ought to have been in Apocalypse 11.

本纲要用以讨论启示录 12 中应该位于启示录 11 的部分。


As in Perl 5, a module is just a kind of package. Unlike in Perl 5, modules and classes are declared with separate keywords, but they're still just packages with extra behaviors.

在 Perl 5 中,一个模块就仅仅是一个包/package. 不同于 Perl 5, 模块与类 在 Perl 6 中是用不同的关键字声明。不过它们仍然只是带着额外操作的包。

A module is declared with the module keyword. There are two basic declaration syntaxes:

一个模块由关键字 module 来声明。这里有两种基本的声明语法:

    module Foo; # rest of scope is in module Foo
                # 下面的作用域都在模块 Foo 内
    module Bar {...}    # block is in module Bar
                       # 块在模块 Bar 内

The first form is allowed only as the first statement in the file.


Since there are no barewords in Perl 6, module names must be predeclared, or use the sigil-like ::ModuleName syntax. The :: prefix does not imply top-levelness as it does in Perl 5. (Use ::* for that.)

因为 Perl 6 中将不允许出现 裸字/bareword, 所以模块名必须得预先声明,否则你就得使用 类似 ::ModuleName 这样的标记语法。与 Perl 5 不同,前缀 :: 不再意味着这是 最高阶。(我们使用 ::* 来代替。)

A bare module declarator declares a global module name in ::*. To declare a module in the current package (or module, or class), use our module. To declare a lexically scoped module, use my module. Module 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).

一个单独的 module 声明符是在 ::* 中声明一个全局模块名。如果想在当前包(或模块 或类)中声明一个模块,请使用 our module. 如果想要声明一个词法作用域模块,请使用 my module. 模块名总是从最近的作用域搜索到最外层作用域。以 :: 开头的名字并不 意味着这是全局的(这点与 Perl 5 不同)。

The ::* namespace is not ``main''. The default namespace for the main program is ::*Main. (Putting module Main; at the top of your program is redundant, except insofar as it tells Perl that the code is Perl 6 code and not Perl 5 code. A bare module; defaults to Main.)

::* 命名空间不是 ``main''. 默认给主程序的命名空间为 ::*Main. (在你的程序顶部 加上 module Main; 是多余的,除了告诉 Perl 下面的代码是 Perl 6 而不是 Perl 5 代码。 一个单独的 module; 默认为 Main. )

Module traits are set using is:

模块的 traits 是用 is 来设定的:

    module Foo is bar {...}

Exportation 导出

Exportation is now done by trait declaration on the exportable item:

对于可导出项,我们现在用一个特殊声明(is export)来实现导出:

                                               # Tagset...
    sub foo is export(:DEFAULT)         {...}  #  :DEFAULT, :ALL
    sub bar is export(:DEFAULT :others) {...}  #  :DEFAULT, :ALL, :others
    sub baz is export(:MANDATORY)       {...}  #  (always exported)
    sub bop is export                   {...}  #  :ALL
    sub qux is export(:others)          {...}  #  :ALL, :others

Importation 导入

All imports are done by default into the current lexical scope (rather than the current package, as in Perl 5).

所有的导入将默认为到当前的词法作用域(而不像 Perl 5, 是到当前包)。

    use Sense ;

You can be explicit about the desired scoping:


    use Sense :my :our<@horse> :state<$haslearnedsome>;

That's pretty much equivalent to:


    use Sense;
    my &common ::= &Sense::common;
    our @horse ::= @Sense::horse;
    state $haslearnedsome ::= $Sense::haslearnedsome;

Versioning 版本号

When at the top of a file you say something like


    module Cat;

or 或

    class Dog;

you're really only giving one part of the name of the module. The full name of the module or class includes other metadata, in particular, the version, and the author.

你只是仅仅给出了模块名的一部分。模块或类的全名包括其他数据, 如版本号和作者。

Modules posted to CPAN or entered into any standard Perl 6 library are required to declare their full name so that installations can know where to keep them, such that multiple versions by different authors can coexist, all of them available to any installed version of Perl.

对于要发表到 CPAN 或者成为任何 Perl 6 标准库的模块,必须要声明全名。 这样安装时才知道保存在哪,由不同作者写就的多版本能共存,所有的这些 都可以给任何已安装版本的 Perl 获取。

The syntax of a versioned module or class declaration has three parts separated by hyphens. The three parts are the short name of the class/module, its version number, and a URI identifying the author (or authorizing authority). For example:

一个带版本号的模块或类由三个分开的连字符来声明。这三部分分别为类或模块名, 它的版本号和一个 URI 来识别作者(或者已批准作者名)。例如:

    class Dog-1.2.1-cpan:JRANDOM;
    class Dog-1.2.1-http://www.some.com/~jrandom;
    class Dog-1.2.1-mailto:[email protected];

Such a declaration automatically aliases the full name of the class (or module) to the short name. So for the rest of the lexical scope, Dog refers to the longer name.

这样一个声明会自动将这个类(或模块)的全名对应(别名)到一个短名上。 在下面的词法作用域中, Dog 将引用长名模块。

If there are extra classes or modules or packages declared within the same file, they implicitly have a long name including the file's version and author, but you needn't declare them again.

如果在同一文件中声明了多个类或模块或包,它们隐含地持有包含文件版本和作者的一个长名, 而你不需要再次声明。

Since these long names are the actual names of the classes, when you say:


    use Dog;

you're really wildcarding the unspecified bits:


    use Dog-(Any)-(Any);

And when you say:


    use Dog-1.2.1;

you're really asking for:


    use Dog-1.2.1-(Any);

Saying 1.2.1 specifies an exact match on the version number, not a minimum match. To match more than one version, put a range operator in parens:

1.2.1 说明你要一个已确定的版本号,而不是一个最小版本号。 要匹配多于一个版本的话,在括号内使用 范围操作符/range operator:

    use Dog-(1.2.1..1.2.3);
    use Dog-(1.2.1..^1.3);
    use Dog-(1.2.1...);

Subversions are wildcarded, so 1.2 really means 1.2.0.... If you say:

子版本可以通过通配获得,所以 1.2 实际上代表 1.2.0.... 如果你这么写:

    use Perl-6;

you're asking for any version of Perl 6. Say:

实际上你在要求任何版本的 Perl 6. 这么写:

    use Perl-6.0;
    use Perl-6.0.0;
    use Perl-;

if you want to lock in a particular set of semantics at some greater degree of specificity. And some large company ever forks Perl, you can say

如果你需要更精确地控制在一个特定范围内,在一些派生 Perl 的大公司里,你可以这么写

    use Perl-6-cpan:TPF

to guarantee that you get the unembraced Perl. :-)

来保证你获得这个特定 Perl. :-)

For wildcards any valid smartmatch selector works:

在通配符中任何合法的 轻巧匹配选择符/smartmatch(eg, | ^ $) 都能运行:

    use Dog-(1.2.1 | 1.3.4)-(/:i jrandom/);
    use Dog-(Any)-(/^cpan\:/)

Parens are optional on a closure smartmatcher. The preceding may also be written:

对于一个 闭合的轻巧匹配/closure smartmatcher 来说,括号是可选的。前面的 也可以这么写:

    use Dog-{$^ver ~~ 1.2.1 | 1.3.4}-{$^auth ~~ /:i jrandom/};
    use Dog-{$^ver ~~ Any}-{$^auth ~~ /^cpan\:/}

In any event, however you select the module, its full name is automatically aliased to the short name for the rest of your lexical scope. So you can just say

在任何情况下,当你使用模块时,在下面的作用域内它的全名会自动对应(别名) 到一个短名上。所以你这么写时

    my Dog $spot .= new("woof");

and it knows (even if you don't) that you mean


    my Dog-1.3.4-cpan:JRANDOM $spot .= new("woof");

Forcing Perl 6 强制使用 Perl 6

To get Perl 6 parsing rather than the default Perl 5 parsing, we said you could force Perl 6 mode in your main program with:

要使用 Perl 6 解析而不用默认的 Perl 5 解析时,你可以在你的主程序中 通过如下方式强制使用 Perl 6:

    use Perl-6;

Actually, you can just start your main program with any of:


    use v6;

Those all specify the latest Perl 6 semantics, and are equivalent to

这些都指定了使用最新版本的 Perl 6, 等同于:

    use Perl-(v6.0.0...)-(Any);

To lock the semantics to 6.0.0, say:

要确定使用 6.0.0, 可以这么写:

    use v6.0.0;

In any of those cases, strictures and warnings are the default in your main program. But if you start your program with a bare version number or other literal:

在上述情况下,主程序是默认开启 严格语法/strict 和 警告/warnings. 但是如果你在你的程序头使用单独的版本号或其他词语:

    "Coolness, dude!";

it runs Perl 6 in ``lax'' mode, without strictures or warnings, since obvously a bare literal in a void context ought to have produced a warning. (Invoking perl with -e6 has the same effect.)

它将在“宽松”模式下运行 Perl 6, 没有严格语法或警告。(如果带警告的话,)一个 没上下文语境的一个单独的词汇很明显应该输出一个警告。(用 -e6 调用 Perl 也有同样效果。)

blog comments powered by Disqus