特殊变量

描述

一个(希望)全面的 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) 。 人机工程学:

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

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

  • %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 的预编译功能。

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

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

  1. use Test;
  2. use MyModule;
  3. 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 为该组件提供已知作者。

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

  1. for $*KERNEL, $*DISTRO, $*VM -> $what {
  2. say $what.^name;
  3. say 'version ' ~ $what.version
  4. ~ ' named ' ~ $what.name
  5. ~ ' by ' ~ $what.auth;
  6. }
  7. # Kernel
  8. # version 4.10.0.42.generic named linux by unknown
  9. # Distro
  10. # version 17.04.Zesty.Zapus named ubuntu by https://www.ubuntu.com/
  11. # VM
  12. # version 2017.11 named moar by The MoarVM Team

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

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

  • %SIG

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

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

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

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

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

  1. react {
  2. whenever signal(SIGINT) {
  3. say "goodbye";
  4. done
  5. }
  6. }
  • $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}

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

  • $’

替换为 $/.postmatch

  • ${^POSTMATCH}

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

  • $LAST_PAREN_MATCH

  • $+

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

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

  • %20#language_documentation_Operators[[]routine] 例程

  • Whatever

可能

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

  • $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次):

  1. for "foo".IO.lines.kv -> $n, $line {
  2. say "{$n + 1}: $line"
  3. }
  4. # OUTPUT:
  5. # 1: a
  6. # 2: b
  7. # 3: c
  8. # 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 的其余部分一样,它是一个根据类型返回各种内容的错误类型或异常

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

  1. try {
  2. fail "Boooh";
  3. CATCH {
  4. # within the catch block
  5. # the exception is placed into $_
  6. say 'within the catch:';
  7. say $_.^name ~ ' : ' ~ $_.message;
  8. $_.resume; # do not abort
  9. }
  10. }
  11. # outside the catch block the exception is placed
  12. # into $!
  13. say 'outside the catch:';
  14. say $!.^name ~ ' : ' ~ $!.message;

以上代码生成以下输出

  1. within the catch:
  2. X::AdHoc : Boooh
  3. outside the catch:
  4. 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 中使用它们。