22 May 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.

Variables

  • 真正意义上的全局变量生存在包 * 里。如 $*UID, @*ARGS, %*ENV
    打印所有环境变量:
    for %*ENV.kv -> $key, $val {
        say "$key => $val";
    }
    如果我们只写 %ENV, 那编译器将从最里面包依次往外搜索到全局包。
    for %ENV.kv -> $key, $val {
        say "$key => $val";
    }
    上面这段代码与 %*ENV 相同。但如果定义了 %ENV 就不一样了:
    my %ENV = ( 'a' => 'b', 'c' => 'd' );
    
    for %ENV.kv -> $key, $val {
        say "$key => $val";
    }
    # output is
    # a => b
    # c => d
  • 文件范围的变量的第二标记为 =. 例如 $=DATA 是你文件内 =begin DATA 句柄的变量名。
    所有的 pod 结构可以通过 %=POD (或类似的)来获得。
  • 词汇范围的变量的第二标记为 ?. 它们是是编译器所知道的值。(运行期的值进入了包 *.)
    例如:$?FILE 和 $?LINE 是你当前的文件和当前行数字。
    #!/usr/bin/pugs
    # the filename is t.pugs
    say $?FILE, $?LINE; #t.pugs3
    可能的变量有:(请参考 S02.pod
    变量名英文解释中文解释举例说明
    $?OSWhich os am I compiled for?当前编译的操作系统如 Win2000 下为 MSWin32
    $?OSVERWhich os version am I compiled for?当前编译操作系统的版本号
    $?PERLVERWhich Perl version am I compiled for?当前编译的 Perl 版本号
    $?FILEWhich file am I in?当前的文件名
    $?LINEWhich line am I at?所在的行号
    $?PACKAGE
    @?PACKAGE
    Which package(s) am I in?所在的包名
    $?MODULE
    @?MODULE
    Which module am I in?所在的模块名
  • 因为 *, =, ? 都可以做为包名使用,所以你可以这么写:%*::ENV, $=::DATA, @?::MODULE

内插/interpolate

  1. 数组内插:要内插整个数组,现在必须使用空中括号[]做下标。
    my @a = ('p', 'e', 'r', 'l');
    say "array @a"; # array @a
    say "array @a[]"; # array p e r l
  2. 散列内插:要内插整个散列,必须得使用空括号或三角符号:
    my %bar = ( 'a' => 'b', 'c' => 'd' );
    print "hash are:\n%bar{}";
    # output is
    # hash are:
    # a       b
    # c       d
    对于一个 Pair 来说,键和值之间插入 tab (制表),整个 Pair 后面插入一个换行。
  3. 子程序内插:为了内插子程序调用结果,必须在前加 & 后加括号:
    sub func {
        return ('f', 'u', 'n', 'c');
    }
    
    print "call &func return &func()"; # call &func return f u n c
    在标量上下文调用函数。(如果返回一个列表,那么列表将做为数组内插。)
  4. 方法内插:为了内插一个没有参数的方法返回值,括号是必须的:
    print "The attribute is $obj.attr().\n"
    同样的,在标量上下文调用方法。(如果返回列表,将其作为数组内插。)
  5. 裸包内插,例子如下:
    my $i = 2;
    say "now \$i is { $i * 2 }"; # now $i is 4
    如果你想让双引号不内插大括号,你可以明确地去掉这功能:
     qq:c(0) "Here are { $two uninterpolated } curlies"; # c(0) 去掉了内插
    q 后面的副词可以设置你只内插标量或数组或散列或什么(见下面详细解说)。例如:
    my $two = 2;
    say q:s 'Here are { $two * 2 } curlies'; # Here are { 2 * 2 } curlies
    这里我们用 :s 限定了只内插标量。

引号副词

Short/短名Long/长名Meaning/意思
:x:execExecute as command and return results / 当成命令运行并返回结果
:w:wordsSplit result on words (no quote protection) / 按字分割(不考虑引号保护)
:ww:quotewordsplit result on words (with quote protection) / 按此分割 (考虑引号保护)
:t:toInterpret result as heredoc terminator / 以 heredoc 形式内插结果
:0:rawNo escapes at all (unless otherwise adverbed) / 无转义(除非有其他副词)
:1:singleInterpolate \\, \q and \' (or whatever) / 内插 \\, \q 和 \' (或其它)
:2:doubleInterpolate all the following / 内插下面所有
:s:scalarInterpolate $ vars / 内插 $ 变量
:a:arrayInterpolate @ vars / 内插 @ 变量
:h:hashInterpolate % vars / 内插 % 变量
:f:functionInterpolate & calls / 内插 & 调用
:c:closureInterpolate {...} expressions / 内插 {...} 表达式
:b:backslashInterpolate \n, \t, etc. (implies :m) / 内插 \n, \t, etc.(暗指 :m)

当以 q 开头时,上面的所有都可以省略冒号,所以我们自动就有了如下形式:

    Form    Same as
    ====    =======
    qx//    q:x//
    qw//    q:w//
    qww//    q:ww//
    qt//    q:t//
    q0//    q:0//
    q1//    q:1//    (same as q//)
    q2//    q:2//    (same as qq//)
    qs//    q:s//
    qa//    q:a//
    qh//    q:h//
    qf//    q:f//
    qc//    q:c//
    qb//    q:b//

你可以定义你自己的引号副词和操作符。所有的大写副词都是保留给用户定义的。 所有在 Latin1 上的 Unicode 也是保留给用户定义的。

Others

  • 根据上面的副词,<< 再也没有了,我们现在这么来写 Heredoc:
    print qq:to/END/
    Give $amount to the man behind curtain number $curtain.
    END
  • 再也没有 C<$#foo> 记法了。用 C<@foo.end> 来代替,空数组返回 -1。
    (多唯数组用 C<@foo.shape[$dimension]> )
    my @a1 = (1,2,4);
    my @a2 = ();
    say @a1.end, @a2.end; # 2-1
  • 而数组的个数可以用 @foo.elems 或 [email protected] 得到。

All is welcomed

Thank God.


blog comments powered by Disqus