A trip to the Yellow Mountain

20 March 2005


I spent this weekend travelling the Yellow(Huang) Mountian with my classmates. 2 days and 260 Yuan, and I think it's worth the time and money.

The most time We do is climbing, having a break, and climbing again.
The first day is a rainy day, and we climbed through the rain and were wetted from head to foot.
It's nearly 19:00 until we arrived the cheap hotel. It's dark then and we can hardly see the road under the feet. luckily, no one hurt.
We planned to have a sight of the famous sunrise in the next day, but the heavy fog disappointed us.
It's just another climbing-day. But with luck, we met the wild monkeys down the mountain road. we threw some pieces of bread to please them, and us.

The deepest thing in my memory is the heaver, or we called them porter. They climbed more than 8 kilometers with heavy goods only to earn 33 Yuan. And it's a shame that they are quicker than us.

To have a full sight within 2 days is a difficult task, and it's a pity we missed the sunrise.
I think I'll go to the Yellow Mountain with my lovely girlfriend in another day.

Now I'm too tired and eager to have a nice sleep. God bless me.


批量转网页编码

15 March 2005


转为 utf-8 是为国际接轨。 :)
Download here!

Code

#!/usr/bin/perl
# convert gb2312 encoding webpage to utf-8 in a directory
use strict;
use warnings;
use Encode qw/from_to/; # load the main func.

# setting
my $dir = 'E:/Fayland/Emag/0503'; # the directory u want to convert.

# get all .html? files
opendir(DIR, $dir);
my @file = readdir(DIR);
closedir(DIR);
@file = grep(/\.html?$/, @file);

# convertion
foreach (@file) {
    # get the file data;
    open(FH, "$dir/$_");
    my @data = ;
    close(FH);
    my $data = join("", @data);
    if ($data =~ /charset\=gb2312/) { # it's not utf-8 yet
        $data =~ s/charset\=gb2312/charset\=utf-8/s;
        from_to($data, "gb2312", "utf8");    
        open(FH, ">$dir/$_");
        print FH $data;
        close(FH);
        print "$_ convert success!\n";
    } else {
        print "$_ is already utf-8\n";
    }
}

rt.cpan.org: Bug

15 March 2005


yap, rt.cpan.org is a bug tracing system to all CPAN modules.
If u are a module author, you should fix the bugs if they exist.
If u are a perlmonk and find some errors when u use some module, u can report a bug on rt.cpan

Today, the two situations occurred to me.

I submitted a bug to Perl6-Pugs.
http://rt.cpan.org/NoAuth/Bug.html?id=11875
It's a installation problem. when I 'svn up', and type 'perl makefile.PL', it always return:

Can't generate the correct Perl6 equivalent for:

    C:\usr\lib

field name: archlib
osname: MSWin32

Please notify the maintainer of this code. (Brian Ingerson for now)
another weird problem. (See weird thing with nmake pugs)
Autrijus replies:
Hi.  It happens because C:\usr\lib did not contain "perl" in it, so
Pugs was confused.  Cc'ing ingy for discussions -- maybe just append
"perl6" to it? maybe prompt?

Thanks,
/Autrijus/
But I think there is another reason causes my problem. forget it for now.

several hours later, I got a email from 'Adam Kennedy':
http://rt.cpan.org/NoAuth/Bug.html?id=11876

Fayland

I have just filed an RT bug against China::IdentityCard::Validate 
regarding it's name, which is unusual and quite out of place.

Countries to not have top level CPAN namespaces.

Must number modules like yours currently exist in the Business:: 
namespace, which you result in your module being better named.

Business::CN::IdentityCard

If I can also recommend another thing, you should consider not exporting 
the function by default, and moving to more of a hybrid style 
object/functional structure so that the module can be used very very 
flexibly, and so that you can create IdentityCard objects as well.

For an example of a _very_ similar module which wraps the same sort of 
functionality in a much more flexible "package", see

Business::AU::ABN

Feel free to copy as much of it as you wish.

Adam Kennedy
It's concerning with my easy module 'China::IdentityCard::Validate'.
I followed his advice, and upload new 'Business::CN::IdentityCard' to pause and delete the old modules.
I tried to modify my module as what he said. but I give up finally, because it's too complex to this easy module.
OO-structure is just too much code to write. I don't like it. :(
Maybe I'll rewrite it later.

God bless me.


纲要十一:模块

14 March 2005


English version: http://dev.perl.org/perl6/synopsis/S11.html

TITLE

Synopsis 11: Modules

纲要 十一:模块

AUTHOR

Larry Wall <[email protected]>

VERSION

  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 的部分。

Modules

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-6.2.7.1;

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;
    module;
    class;

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. 但是如果你在你的程序头使用单独的版本号或其他词语:

    v6.0.0;
    v6;
    6;
    "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 也有同样效果。)


纲要十:包

12 March 2005


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 来获得你的包名。


给 eclipse 安装 EPIC plug-in

12 March 2005


听 Autrijus Tang 对 eclipse 赞不绝口,不免想试试这东西。
http://www.eclipse.org/downloads/index.php 下了 Eclipse Platform SDK 3.0.1, Windows.
下完了解压缩到随便某目录下就能运行。

没装过 plug-in 的 eclipse 对 Perl 可以说是一点也不支持。网上的介绍文章都是关于 eclipse 和 java 的,最多还有个 C++. 我 Google 了一下 'eclipse perl', 搜索到 EPIC 插件。
网址:http://e-p-i-c.sourceforge.net/

说出来不怕您笑话。:),下了 http://e-p-i-c.sourceforge.net/downloads/org.epic.updatesite_0.3.0_20040711.zip 却不会安装。
压缩包里没有 README 或 INSTALL 啥的,啥可读文件都没有。解压缩到 eclipse 目录里也不管用。
后来在 http://e-p-i-c.sourceforge.net/faq.html#Installation 找到个另外的方法。用 eclipse 的 update 功能。可丫的学校网络实在糟糕,安装那插件时每到 org.epic.debug_0.2.0.jar 总是出错要你重试。试了四五次都不行。真丫折腾人。

后来想着既然 update 到网站 http://e-p-i-c.sourceforge.net/updates ,我干脆让它到 http://localhost 好了。
将下来的 org.epic.updatesite_0.3.0_20040711.zip 解压缩到 htdocs 里。然后设置 eclipse Help > Software and Updates > Find and Install... , Search for new features to install, Add Update Site... , 在 URL 里填入 http://localhost/org.epic.updatesite .然后安装就及其顺利了。

在写这份纪录的时候,还发现了在 Add Update Site... 下面还有个 Add Local Site... 可以直接到本地文件夹。

总得来说 eclispe 还是不错的。首先它是免费的开源软件,网上有很多丰富的插件/plug-in. 其次安装完 EPIC 后的 eclispe 有点类似于 Kodomo. 功能还是挺多的,有

  1. 语法加亮 / Syntax Highlighting
  2. 闲时语法检查(带有注释旋停) / On the fly syntax check (with annotation hover)
  3. 内容加速器(帮助,类似自动补充函数名等关键字) / Content assist
  4. 快速参考(对某内建函数或模块) / Quick reference feature
  5. 显示已用模块和子程序 / Outline view with used modules and subroutines
  6. Perl Debug
  7. 更多的参见 http://e-p-i-c.sourceforge.net/main.html#Features
决定以后抛弃 UE32, 转向 eclispe.

:) May all good luck.


中国身份证验证模块

11 March 2005



Synopsis 13: 重载

09 March 2005


English version: http://dev.perl.org/perl6/synopsis/S13.html

TITLE

Synopsis 13: Overloading

纲要 13:重载

AUTHOR

Larry Wall <[email protected]>

VERSION

  Maintainer: Larry Wall 
  Date: 2 Nov 2004
  Last Modified: 2 Dec 2004
  Number: 13
  Version: 3

Overview 概述

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

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

Multiple dispatch 多重分派

The overloading mechanism of Perl 5 has been superseded by Perl 6's multiple dispatch mechanism. Nearly all internal functions are defined as multi subs or multi methods on generic types. Built-in operators are merely oddly named functions with an alternate call syntax. All you have to do to overload them is to define your own multi subs and methods that operate on arguments with more specific types.

Perl 5 中的重载机制将被 Perl 6 中的多重分派机制所取代。几乎所有的内部函数 都是由传递一般类的 multi 子程序或 multi 方法所定义。内置运算符不过是 奇怪的函数名加上不同的调用语法而已。要重载它们的话,你只需要定义你自己的 multi 子程序和方法,然后通过指定特定类型的参数来达成目的。

For unary operators, this makes little effective difference, but for binary operators, multiple dispatch fixes the Perl 5 problem of paying attention only to the type of the left argument. Since both argument types are used in deciding which routine to call, there is no longer any trickery involving swapping the arguments to use the right argument's type instead of the left one. And there's no longer any need to examine a special flag to see if the arguments were reversed.

对于一元运算符,没有什么大变化。但对于二元运算符,多重分派修正了 Perl 5 中仅仅对左边的参数类型加以注意的错误。因为在多重分派中所有的参数类型 对你要调用哪个程序都有影响,所以再也不需要通过调换参数,用右边参数类型来代替 左边而达成调用欺骗。而且再也不需要检查一个特定标记来决定这个参数是否保留。

For much more about multiple dispatch, see A12.

需要更多关于多重分派的信息,请参考 A12.

Syntax 语法

There is no longer any special use overload syntax separate from the declarations of the multi routines themselves. To overload an existing built-in sub, say something like:

除了 multi 程序申明外,再也没有任何特殊的 use overload 语法。 如果要重载一个已存在的内建子程序,这用这么写:

    multi sub *uc (TurkishStr $s) {...}

Now if you call uc() on any Turkish string, it will call your function rather than the built-in one. Putting the multi into the * namespace makes it show up in everyone's packages, but as long as no one else defines a version of uc on TurkishStr, there's no collision. The types of the invocants are included in the ``long name'' of any multi sub or method.

现在如果你用 土耳其/Turkish 字符串来调用 uc, 那么它将调用你刚写的函数 而不是内建函数。将 multi 放在 * 命名空间可以让此子程序在所有人的 包/package 中使用,只用没有其他人也定义了一个 TurkishStr 版本的 uc ,那就没有任何冲突。 调用的类别将保护在任何 multi 子程序或方法的“长名”内。

If you want to overload string concatenation for Arabic strings so you can handle various ligatures, you can say:

如果你想对 阿拉伯语/Arabic 字符串 重载字符串联以便处理不同的 连字/ligatures, 你可以这么写:

    multi sub *infix:<~>(ArabicStr $s1, ArabicStr $s2) {...}
    multi sub *infix:<~>(Str $s1, ArabicStr $s2) {...}
    multi sub *infix:<~>(ArabicStr $s1, Str $s2) {...}

Ordinary methods can be turned into multi methods within the class definition:

一般方法可以在类定义中转换成 多重/multi 方法:

    class MyNum {
        multi method abs(MyNum $x) {...}
        ...
    }

Likewise operators on your new type can appear in the class:

同样地,传递新类型的运算符也可以包含在类里:

    class MyNum {
        multi method prefix:<+> (MyNum $x) {...} # what we do in numeric context
        multi method prefix:<~> (MyNum $x) {...} # what we do in string context
        multi method prefix: (MyNum $x) {...} # what we do in boolean context
        ...
    }

Binary operators may be declared as commutative:

二元运算符还可以被定义成可交换的:

    multi sub infix:<+> (Us $us, Them $them) is commutative { myadd($us,$them) }

That's equivalent to:

这等同于:

    multi sub infix:<+> (Us $us, Them $them) { myadd($us,$them) }
    multi sub infix:<+> (Them $them, Us $us) { myadd($us,$them) }

Note the lack of * on those definitions. That means this definition of addition is only in effect within the scope of the package in which infix:<+> is defined. Similar constraints apply to lexically scoped multi subs. Generally you want to put your multi subs into the * space, however, so that they work everywhere.

注意这些定义中都没有 *. 这表示新增的这个定义只对 infix:<+> 所定义的 包作用域有效。相同的约束作用于在词法作用域的 多重/multi 子程序。不过通常你应该 将 多重/multi 子程序放在 * 空间内,这样它们能在任何地方使用。

The use overload syntax had one benefit over Perl 6's syntax in that it was easy to alias several different operators to the same service routine. This can easily be handled with Perl 6's aliasing:

use overload 语法相较于 Perl 6 语法还有个优点,它可以简单的使用别名让许多不同 的运算符使用同一个服务程序。通过 Perl 6 的别名,这也可以轻松搞定:

    multi sub unimpl (MyFoo $x) { upchuck(); }
    &infix:<+> ::= &unimpl;
    &infix:<-> ::= &unimpl;
    &infix:<*> ::= &unimpl;
    &infix: ::= &unimpl;

Fallbacks 预设机制

Dispatch is based on a routine's signature declaration without regard to whether the routine is defined yet. If an attempt is made to dispatch to a declared but undefined routine, Perl will redispatch to AUTOSUBDEF or AUTOMETHDEF as appropriate to define the routine. This provides a run-time mechanism for fallbacks. By default, these declarations are taken at face value and do not specify any underlying semantics. As such, they're a ``shallow'' interpretation.

分派机制只是基于程序的声明信号,而不管这个程序是否已经被定义。如果试图分派 一个已声明却未定义的程序, Perl 将重分派到 AUTOSUBDEFAUTOMETHDEF 来定义这个程序。这就提供了一个运行时的预设机制。默认这些声明将根据外表值来 判断而不指定任何潜在的语意。也就是说,这是种“浅层”解释。

However, sometimes you want to specify a ``deep'' interpretation of your operators. That is, you're specify the abstract operation, which may be used by various shallow operators. Any deep multi declarations will be ``amplified'' into all the shallow operators that can be logically based on it. If you say:

但是,有时候你需要对你的运算符指定一个“深层”解释。也就是说,你指定个抽象 运算符,它可能被多个浅层操作符所调用。任何一个深层多重声明都会被“扩大”到所有 逻辑上基于它的浅层运算符。

    multi sub infix:<%> (Us $us, Them $them) is deep { mymod($us,$them) }

then

那么

    multi sub infix:<%=> (Us $us, Them $them) { $us = $us % $them }

is also generated for you (unless you define it yourself). The mappings of magical names to sub definitions is controlled by the %?DEEPMAGIC compiler hash. Pragmas can influence the contents of this hash over a lexical scope, so you could have different policies on magical autogeneration. The default mappings correspond to the standard fallback mappings of Perl 5 overloading.

也会被产生(除非你自己定义它)。 魔术名字(magical names)到子程序声明的映射由 %?DEFPMAGIC 编译器散列 所约束。编译指示(Pargmas)能在词法作用域范围内影响这个散列的值,所以你 可以在魔术自动生成上有很多不同的策略。默认的映射与 Perl 5 重载的标准预设 映射相应。


Synopsis 1 / 纲要一

08 March 2005


English version: http://dev.perl.org/perl6/synopsis/S01.html
繁体版本:http://svn.openfoundry.org/p6l10n/zh_tw/S01.pod
本简体版本参考了 plasma 翻译的繁体版本。它将列于 http://svn.openfoundry.org/p6l10n/zh_cn/S01.pod

TITLE

纲要一:概述

AUTHOR

Larry Wall <[email protected]>

VERSION

  Maintainer: Luke Palmer 
  Date: 10 Aug 2004
  Last Modified: 18 Aug 2004
  Number: 1
  Version: 0

This document summarizes Apocalypse 1, which covers the initial design concept. (These Synopses also contain updates to reflect the evolving design of Perl 6 over time, unlike the Apocalypses, which are frozen in time as ``historical documents''. These updates are not marked--if a Synopsis disagrees with its Apocalypse, assume the Synopsis is correct.)

这份文档是对涵盖了最初设计概念的启示录一的总结。(这些纲要还会更新,以 反映随着时间而演变的 Perl 6 设计,这不同与做为“历史文献”的启示录,它们 已被冻结而不再更新。这些更新不会被标出来——如果纲要与启示录有所抵触,请 以纲要为准。)

The other basic assumption is that if we don't talk about something in these Synopses, it's the same as it was in Perl 5.

另一个基本假设为,如果某样东西没有在这些纲要中提起,那就跟 Perl 5 中是一样的。

Random Thoughts / 随想

  • The word ``apocalypse'' historically meant merely ``a revealing'', and we're using it in that unexciting sense.

    “启示录”的原来意思仅为“揭示”,而我们用的就是这个不让人激动的意思。

  • If you ask for RFCs from the general public, you get a lot of interesting but contradictory ideas, because people tend to stake out polar positions, and none of the ideas can build on each other.

    如果你向一般公众请求 RFCs, 你会得到一堆有趣却相互抵触的主意,这是因为 每个人的立足点都不相同,而且这些主意都没办法互为基石。

  • Larry's First Law of Language Redesign: Everyone wants the colon.

    Larry 语言重设计第一定律:人人都要冒号。

  • RFCs are rated on ``PSA'': whether they point out a real Problem, whether they present a viable Solution, and whether that solution is likely to be Accepted as part of Perl 6.

    ``PSA'' 是用来评价 RFCs 的工具:他们是否找出了实际存在的问题(Problem), 他们是否给出了可行性解答方案(Solution),还有这个方案能不能被接受为 Perl 6 的一部分。

  • Languages should be redesigned in roughly the same order as you would present the language to a new user.

    语言重设计的顺序大致上应当与将该语言介绍给新用户的顺序一样。

  • Perl 6 should be malleable enough that it can evolve into the imaginary perfect language, Perl 7. This darwinian imperative implies support for multiple syntaxes above and and multiple platforms below.

    Perl 6 应当有足够的可延展性,这样它可以进一步进化成想像中的完美语言, Perl 7. 这种达尔文天命暗示着对上要支持多语法,对下要支持多平台。

  • Many details may change, but the essence of Perl will remain unchanged. Perl will continue to be a multiparadigmatic, context-sensitive language. We are not turning Perl into any other existing language.

    许多细节或许会改变,但 Perl 的本质不会有任何变化。Perl 仍然是多例证的, 上下文相关的语言。我们不会把 Perl 变成现有的其他语言。

  • Migration is important. The perl interpreter will assume that it is being fed Perl 5 code unless the code starts with a ``class'' or ``module'' keyword, or you specifically tell it you're running Perl 6 code in some other way, such as by:

    移植是非常重要的。perl 解释器会假设它所收到的是 Perl 5 代码,除非代码以 ``class'' 或 ``module'' 关键字开始,或者你用其它方式明确地告诉它你要运行 Perl 6 代码:

        #!/usr/bin/perl6
        use v6.0;
        v6;

  • Scaling is one of those areas where Perl needs to be multiparadigmatic and context sensitive. Perl 5 code is not strict by default, while Perl 6 code is. But it should be easy to relax with -e or maybe even a bare version number:

    延展性是另一个 Perl 为什么要是多例证和上下文相关的地方。Perl 5 代码默认并非 语法严格的,不过 Perl 6 是。但是你可以很简单地用 -e 来关闭它,或者仅仅用 一个单纯的版本号:

        perl -e '$x = 1'
        #!/usr/bin/perl -e
        $x = 1;
        #!/usr/bin/perl
        v6; $x = 1;

  • It must be possible to write policy metamodules that invoke other modules on the user's behalf.

    应该可以写策略超模块,它可以根据用户的需求调用其它模块。

  • If you want to treat everything as objects in Perl 6, Perl will help you do that. If you don't want to treat everything as objects, Perl will help you with that viewpoint as well.

    如果你想要将 Perl 6 的每样东西都视为对象,Perl 会帮你做到。如果你不想 如此,Perl 也会依你。

  • Operators are just functions with funny names and syntax.

    操作符只是有着有趣名字和语法的函数。

  • Language designers are still necessary to synthesize unrelated ideas into a coherent whole.

    语言设计者还是需要将一些没有关联的主意综合成一个一致的整体。


The project of Synopsis localization

07 March 2005


I heard from hoowa that the TaiWanese perlmonks would launch the translation work of 'Perl 6 Synopsis'. That's great and I want to join them.

But it's out of luck today. After missing Autrijus Tang two times, I caught him at the irc.freenode.com #perl6 finally. He welcomed me and asked hcchien to send me a invitation email so that I can use 'svn commit' to add/update the document.

The 'p6l10n' project's website: http://rt.openfoundry.org/Foundry/Project/?Queue=279
The Subversion/svn: http://svn.openfoundry.org/p6l10n/

I find it's difficult for me to do all myself. Lucky, I'll do my translation work based on the work of zh_tw. Maybe I'll use Office/Word to convert Trad.Chinese to Simp.Chinese and correct the glossary/term difference. That's easy.

Another way, I'll do the translation work by myself, word by word. Of course, the ever done of translation by TaiWanese are excellent reference.

I'm not sure which will be selected. It's decided by how busy I am.

God bless all move smooth.