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::Path 或 IO::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::AutoLines 和 LN 模块简化此操作。
- $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 中使用它们。