Wait the light to fall

Perl 5 到 Raku 指南 - 特殊变量

焉知非鱼

描述 #

一个(希望)全面的 Perl 5 特殊变量列表及其 Raku 等价物,并在必要时记录它们之间的变化。

注意 #

本文档试图引导读者从 Perl 5 中的特殊变量到 Raku 中的等效变量。有关 Raku 特殊变量的完整文档,请参阅每个变量的 Raku 文档。

特殊变量 #

通用变量 #

  • $ARG
  • $_

值得庆幸的是, $_ 是 Perl 5 中的常规默认变量。Raku 的主要区别在于现在你可以在它身上调用方法。 例如,Perl 5 的 say $_ 可以在 Raku 中以 $_.say 表示。 此外,因为它是默认变量,您甚至不需要使用变量名称。 前面的例子也可以 通过使用 .say 实现。

  • @ARG
  • @_

由于 Raku 现在具有函数签名,您的参数可以去那里,而不是依赖于 @_。 事实上,如果你使用函数签名,使用 @_ 会吐出你告诉它不能覆盖一个现有签名。

但是,如果您不使用函数签名,则 @_ 将包含您传递给函数的参数, 就像它在Perl 5中那样。再次,与 $_ 一样 ,您可以在其上调用方法。 与 $_ 不同,你不能假设 @_ 为 这些方法的默认变量(即 @_.shift works, .shift 不 work)。

  • $LIST_SEPARATOR
  • $"

目前,Raku 中没有与 List Separator 变量等效的设计文档 S28 在那里说 不是一个,所以你可能不想屏住呼吸。

  • $PROCESS_ID
  • $PID
  • $$

在 Raku 中用 $*PID 替换 $$

  • $PROGRAM_NAME
  • $0

您可以通过 $*PROGRAM-NAME 访问 Raku 中的程序名称 。 注意: Raku 中的 $0 是保持正则表达式匹配中第一个捕获值的变量(即捕获变量现在从 $0 而不是 $1 开始 )。

  • $REAL_GROUP_ID
  • $GID
  • $(

在 Raku 中,组信息由 $*GROUP 处理 ,它包含一个 IntStr 类型的对象 因此 可以在字符串或数字上下文中使用。 因此,组ID通过 +$*GROUP 获得 , 而组名通过 ~$*GROUP 获得 。

  • $EFFECTIVE_GROUP_ID
  • $EGID
  • $)

Raku目前似乎没有提供有效的组ID。

  • $REAL_USER_ID
  • $UID
  • $<

在 Raku 中,用户信息由 $*USER处理 ,后者持有 IntStr 类型的对象,因此可以 可以在字符串或数字上下文中使用(这类似于处理组信息的方式) 由 $*GROUP 对象)。 因此,用户ID通过 +$*USER 获得 ,而用户名通过 ~$*USER 获得 。

  • $EFFECTIVE_USER_ID
  • $EUID
  • $>

Raku当前似乎没有提供有效的用户ID。

  • $SUBSCRIPT_SEPARATOR
  • $SUBSEP
  • $;

Raku中不包含下标分隔符变量。坦率地说,如果你的Perl 5代码正在使用它,那就是 几乎可以肯定,真的很老。

  • $a
  • $b

$a$b 在 Raku 中没有特殊含义 .sort() 不会将它们用于任何特殊的东西。 他们只是常规的旧变量。 通过使用具有更多功能的占位符参数的块来扩展此功能。 占位符变量是使用 ^twigil 创建的 (例如 $^z 。它们可以在裸块中使用或在没有显式参数列表的子程序。 块的参数将分配给占位符 Unicode 顺序中的变量。 I. e。 即使变量出现在块中的顺序 ($^q, $^z, $^a) ,它们将按顺序分配 ($^a, $^q, $^z) 。 人机工程学:

sort { $^a cmp $^z }, 1, 5, 6, 4, 2, 3;
# OUTPUT: «(1 2 3 4 5 6)␤» 
sort { $^g cmp $^a }, 1, 5, 6, 4, 2, 3;
# OUTPUT: «(6 5 4 3 2 1)␤» 
for 1..9 { say $^c, $^a, $^b; last }
# OUTPUT: «312␤» 

有关占位符变量的更多信息,请参阅此页面

  • %ENV

%ENV已被Raku中的%*ENV取代。请注意,此哈希的键可能不完全是 在Perl 5和Raku之间相同。例如, Raku的%ENV中缺少OLDPWD 。

  • $OLD_PERL_VERSION
  • $]

Raku 的运行版本由 $*PERL 特殊变量保存,即一个对象。 正在运行的版本是 通过 $*PERL.version 检索 ,返回类似 v6.c 的内容 ; Perl 的完整字符串化版本解释器是通过 ~$*PERL 获得的 ,它返回类似于 Raku(6.c)的内容 。

  • $SYSTEM_FD_MAX
  • $^F

虽然设计文件(S28)表明这可能会变成 $*SYS_FD_MAX ,但这还没有b被实现。

  • @F

[需要进一步研究]此时有点混乱。 设计文档S28表示 @F in Perl 5在Raku中被 @_ 取代 ,但目前还不清楚它是如何工作的。 另一方面,它是目前的 有点问题,因为 Perl 5 to Raku Translation doc 指出 -a-F 命令 - rakudo 尚未实现行开关。

  • @INC

Raku 中不再存在。请使用“use lib”来操作要搜索的模块存储库。 该 最接近 @INC 的是 $*REPO。 但这与@INC完全不同 因为 Raku 的预编译功能。

# Print out a list of compunit repositories 
.say for $*REPO.repo-chain;
  • %INC

Raku 中不再存在。因为每个 Repository 都负责记住哪些模块已经装好了。 您可以获得所有已加载模块(编译单元)的列表,如下所示:

use Test;
use MyModule;
say flat $*REPO.repo-chain.map(*.loaded); #-> (MyModule Test) 
  • $INPLACE_EDIT
  • $^I

S28 建议使用 $*INPLACE_EDIT,但它尚不存在。

  • $^M

S28 建议使用 $*EMERGENCY_MEMORY,但它尚不存在。

  • $OSNAME
  • $^o

这有点不清楚。 它可能取决于你的意思是“操作系统的名称” 作为设计文档 S28 有三个不同的建议,所有建议都给出了不同的答案。

目前有三个主要对象包含有关“运行环境”的信息:

  • $*KERNEL 提供有关正在运行的操作系统内核的信息;
  • $*DISTRO 提供有关操作系统分发的信息;
  • $*VM 提供有关 Raku 的运行后端机器的信息。

以上所有对象都有共同的方法:

  • version 提供该组件的版本号;
  • name 提供该组件的助记符名称;
  • auth 为该组件提供已知作者。

作为一个简短示例,以下代码打印有关上述所有组件的信息:

for $*KERNEL, $*DISTRO, $*VM -> $what {
    say $what.^name;
    say 'version '  ~ $what.version
        ~ ' named ' ~ $what.name
        ~ ' by '    ~ $what.auth;
}
 
# Kernel 
# version 4.10.0.42.generic named linux by unknown 
# Distro 
# version 17.04.Zesty.Zapus named ubuntu by https://www.ubuntu.com/ 
# VM 
# version 2017.11 named moar by The MoarVM Team 

上面所有的 Str 方法产生了当前时间的信息的短版本名字 。

所有对象都有其他方法,在尝试识别正确运行的实例时非常有用, 有关更多信息,请使用 <.^methods> 来内省以上所有内容。

  • %SIG

没有等效变量。 要在接收信号时执行代码,您可以调用 signal 子程序,返回可以点击的 Supply

$SIG{"INT"} = sub { say "bye"; exit }
signal(SIGINT).tap: { say "bye"; exit }; loop {}

或者,如果您有一个通用代码,想知道它得到了哪个信号:

signal(SIGINT).tap: -> $signal { say "bye with $signal"; exit }; loop {}

在事件驱动的情况下使用信号的更惯用的方式:

react {
    whenever signal(SIGINT) {
        say "goodbye";
        done
    }
}
  • $BASETIME
  • $^T

在 Raku 中用 $*INIT-INSTANT 替换 。 与 Perl 5 不同,这不是自纪元以来的秒数,而是一个 Instant 对象,以原子秒计,带有分数。

  • $PERL_VERSION
  • $^V

$] 一样,这已被 $*PERL.version 取代。

  • ${^WIN32_SLOPPY_STAT}

在 Raku 中没有类似的东西。

  • $EXECUTABLE_NAME
  • $^X

这已被 $*EXECUTABLE-NAME 取代 。 请注意,还有 $*EXECUTABLE ,这在 Raku 中是一个 IO 对象。

与正则表达式相关的变量 #

性能问题 #

如下所示, $``, $&$’从 Raku 中删除了,主要由$/` 和它的变体代替, 消除它们,Perl 5 中的相关性能问题不适用。

  • $<digits> ($1, $2, ...)

Raku 中的这些现有变量与 Perl 5 中的相同,除了它们现在从 $0 开始而不是 $1。 此外,它们是匹配变量 $/ 中索引项的同义词。 例如 $0 相当于 $/[0], $1相当于$/[1]`等。

  • $MATCH
  • $&

$/ 现在包含匹配对象,因此 $& 的 Perl 5 行为可以通过字符串化来获得,即 ~$/ 。 请注意,虽然 $/.Str 也可以工作, 但 ~$/ 目前是更常见的用法。

  • ${^MATCH}

由于以前的性能问题已经废除,因此 Raku 中没有使用此变量。

  • $PREMATCH
  • $`

替换为 $/.prematch

  • ${^PREMATCH}

由于以前的性能问题已经废除,因此 Raku 中没有使用此变量。

  • $POSTMATCH
  • $'

替换为 $/.postmatch

  • ${^POSTMATCH}

由于以前的性能问题已经废除,因此 Raku 中没有使用此变量。

  • $LAST_PAREN_MATCH
  • $+

在 Raku 中不存在,但你可以使用 $/[*-1].Str 获得相同的信息。($/[*-1] 将是匹配对象,而不是实际的字符串)。

如果您想了解其工作原理,可以查看以下文档:

可能

虽然设计文件并不总是最新的。

  • $LAST_SUBMATCH_RESULT
  • $^N

S28 建议 $*MOST_RECENT_CAPTURED_MATCH ,但似乎没有任何实现的变量匹配 $^N.

  • @LAST_MATCH_END
  • @+

与大多数正则表达式相关的变量一样,此功能至少部分地移至 Raku 中的 $/ 变量。或者,在这种情况下,编号变量是索引的别名。 偏移是通过使用 .to 方法找到。 例如, 第一个偏移是 $/[0].to ,它与 $0.to 同义。 Perl 5 提供的 $+[0]$/.to 提供。

  • %LAST_PAREN_MATCH
  • %+

再一次,我们转移到 $/。 前面的 $+{$match}$/{$match}

  • @LAST_MATCH_START
  • @-

类似于使用 .to 方法替换 @+ ,使用 $/ 上的 .from 方法替换 @- 及其变化。 第一个偏移是 $/[0].from 或等价的 $0.from。 Perl 5 的 $-[0]$/.from

  • %LAST_MATCH_START
  • %-

%+ 非常相似 ,使用 %-{$match} 将替换为 $/{$match}

  • $LAST_REGEXP_CODE_RESULT
  • $^R

没有等价物。

  • ${^RE_DEBUG_FLAGS}

没有等价物。

  • ${^RE_TRIE_MAXBUF}

没有等价物。

与文件句柄相关的变量 #

  • $ARGV

读取行时当前文件的名称可以通过 $*ARGFILES.path 获得。

  • @ARGV

@*ARGS 包含命令行参数。

  • ARGV

这被 $*ARGFILES 取代 。

  • ARGVOUT

由于尚未实现 -i 命令行开关,因此还没有相当于 ARGVOUT 的功能 。

  • $OUTPUT_FIELD_SEPARATOR
  • $OFS
  • $

目前没有明显的等价物

  • $INPUT_LINE_NUMBER
  • $NR
  • $.

不存在直接替代品。

迭代时使用 行方法 IO::PathIO::Handle 类型,您可以在其上调用 .kv 方法 获取交错的索引和值列表(然后每个循环迭代2次):

for "foo".IO.lines.kv -> $n, $line {
    say "{$n + 1}: $line"
}
# OUTPUT: 
# 1: a 
# 2: b 
# 3: c 
# 4: d 

对于 IO::CatHandle 类型(其中 $*ARGFILES 是一个),你可以使用 on-switch hook 在句柄开关上重置行号,并手动递增。 另请参阅 IO::CatHandle::AutoLinesLN 模块简化此操作。

  • $INPUT_RECORD_SEPARATOR
  • $RS
  • $/

这可以通过文件句柄上的 .nl-in 方法访问 。 例如。 $*IN.nl-in

  • $OUTPUT_RECORD_SEPARATOR
  • $ORS
  • $\

这可以通过文件句柄上的 .nl-out 方法访问 。 例如 $*OUT.nl-out

  • $OUTPUT_AUTOFLUSH
  • $|

没有全球替代品。 对于其他设置,TTY 句柄默认是无缓冲的 out-buffer 设置为零或者使用 :!out-buffer 在特定的 IO::Handle上和 open 一块使用 。

  • ${^LAST_FH}

在 Raku 中没有实现。

与格式相关的变量 #

Raku中没有内置格式。

错误变量 #

关于 Raku 中的错误变量如何变化,因此这里不再详细说明。

引用 Raku docs 中的说法,$! 是错误变量。

与 Raku 的其余部分一样,它是一个根据类型返回各种内容的错误类型或异常

特别是在处理异常时, $! 提供有关抛出异常的信息, 假设程序没有停止:

try {
    fail "Boooh";
    CATCH {
        # within the catch block 
        # the exception is placed into $_ 
        say 'within the catch:';
        say $_.^name ~ ' : ' ~ $_.message;
        $_.resume; # do not abort 
    }
}
 
# outside the catch block the exception is placed 
# into $! 
say 'outside the catch:';
say $!.^name ~ ' : ' ~ $!.message;

以上代码生成以下输出

within the catch:
X::AdHoc : Boooh
outside the catch:
X::AdHoc : Boooh

因此,如前所述, $! 变量保存异常对象。

与解释器状态相关的变量 #

  • $COMPILING
  • $^C
  • $^D

目前没有这些变量的等价物。

  • ${^ENCODING}

虽然在 Perl 5 中已弃用 ,但在 $?ENC 中 可能有某种等价物 ,但这还远未明朗。

  • ${^GLOBAL_PHASE}

没有 Raku 等价物。

  • $^H
  • %^H
  • ${^OPEN}

在 Raku 中可能有也可能没有这些等价物,但它们是内部的,你不应该搞乱 与他们在一起 - 当然,如果您对 Raku 的理解需要您阅读本文,那么肯定不会阅读该文献…

  • $PERLDB
  • $^P

Raku 调试器与 Perl 5 调试器相似的可能性最小,此时此处也是如此,似乎不等于这个变量。

  • ${^TAINT}

S28 声称这个变量是“待定”的。 目前不在 Raku 中。

  • ${^UNICODE}
  • ${^UTF8CACHE}
  • ${^UTF8LOCALE}

这些与 Unicode 相关的变量似乎不存在于 Raku 中,但是 - 也许? - 可能在某处有 $?ENC 类似物吗? 然而,这完全未经证实。

弃用和删除变量 #

不言而喻,因为已经从 Perl 5 中删除了这些,所以应该没有必要告诉你如何在 Raku 中使用它们。