在分配给变量之前在 Perl 6 程序中使用它

  • 本文关键字:程序 Perl 分配 变量 raku
  • 更新时间 :
  • 英文 :


我想用我的程序将文字分配给文件末尾的一些变量,但要更早地使用这些变量。我想出的唯一方法是:

my $text;
say $text;
BEGIN {    
$text = "abc";
}

有没有更好/更惯用的方法?

去功能。

改为创建子例程:

say text();
sub text { "abc" }


更新(谢谢雷夫!结合您的反馈,包括使用term:<>的参考):

在上面的代码中,我最初省略了调用text的括号,但始终包含它们以防止解析器误解我们的意图会更易于维护。例如

say text();          # "abc" 
say text() ~ text(); # "abcabc"
say text;            # "abc", interpreted as: say text()
say text ~ text;     # ERROR, interpreted as: say text(~text())
sub text { "abc" };

为了避免这种情况,你可以text一个术语,这有效地使空字text的行为与text()相同:

say text;        # "abc",    interpreted as: say text() 
say text ~ text; # "abcabc", interpreted as: say text() ~ text()
sub term:<text> { "abc" };

对于编译时优化和警告,我们还可以向其添加pure特征(感谢 Brad Gilbert!is pure断言,对于给定的输入,该函数"始终产生相同的输出,没有任何额外的副作用":

say text;        # "abc",    interpreted as: say text() 
say text ~ text; # "abcabc", interpreted as: say text() ~ text()
sub term:<text> is pure { "abc" };

与 Perl 5 不同,在 Perl 6 中,BEGIN不一定是块。 但是,必须先查看词法定义才能使用,因此必须在say之前完成BEGIN块。

BEGIN my $text = "abc";
say $text;

不确定这是否构成对您的问题的答案。

首先,改写一下您的问题:

有哪些选项可以简洁地引用其初始化代码出现在同一源文件中更靠后的变量(或常量等)?

发布声明例程

say foo;
sub foo { 'abc' }

当 P6 编译器分析没有符号的标识符时,它会检查它是否已看到该标识符的声明。如果没有,那么它假设标识符对应于一个例程,该例程稍后将被声明为"listop"例程(它接受零个或多个参数)并继续前进。(如果它的假设被证明是错误的,它就会失败编译。

因此,您可以使用例程,就好像它们是克里斯托弗·巴顿(Christopher Bottom)答案中描述的变量一样。

首次使用时自动声明变量

严格是一种"编译指示",用于控制 P6 编译器在解析以符号开头的尚未声明的变量/常量时的反应。

P6 在打开严格模式的情况下启动程序。这意味着编译器将坚持预先声明任何符号变量/常量。(预声明是指在使用变量/常量之前以文本形式出现的显式声明。

但是您可以编写use strictno strict来控制严格编译指示在给定的词法范围内是打开还是关闭,因此这将起作用:

no strict;
say $text;
BEGIN {    
$text = "abc";
}

警告no strict生效(不幸的是,这是大多数编程语言的工作方式)使得变量名称的意外拼写错误比打开use strict模式更麻烦。

在第一次使用变量的同一语句中显式声明变量

不必将声明编写为单独的语句。您可以在同一语句或表达式中声明和使用变量:

say my $text;
BEGIN {    
$text = "abc";
}

警告如果在完全相同的词法范围内重复my $bar,编译器将发出警告。相比之下,say my $bar = 42; if foo { say my $bar = 99 }会在没有警告的情况下创建两个不同的$bar变量。

在运行时初始化

上面显示的BEGIN相位器在编译时运行(在my声明之后,这也发生在编译时,但在运行时发生的say之前)。

如果要改为在运行时初始化变量/常量,请改用INIT

say my $text;
INIT {    
$text = "abc";
}

INIT代码在任何其他运行时代码之前运行,因此初始化仍会在执行say之前进行。

使用正电子(ym)变量

鉴于对您的问题的字面解释,"正电子"或ym变量将是另一种解决方案。(此功能不是内置的。我之所以包括它,主要是因为我在回答这个问题后遇到了它,并认为它属于这里,至少在娱乐价值方面。

此类变量的初始化和计算从使用它的最后一个语句开始,并相对于代码的文本顺序向后发生。

这是达米安"疯狂的科学家"康威在他 2011 年的演讲中讨论的几个听起来很疯狂但实际上有效且有用的概念之一 时间四水体虚拟纳米机器编程在多个拓扑连接的量子相对论平行时空...变得简单!

这是他关注这些变量的链接。

(整个演讲令人愉悦,特别是如果你对物理感兴趣;编程技术;观看极具创造力的神童;和/或享受出色的演讲技巧和幽默。

创建PS杂注?

就酷度而言,与我刚刚介绍的达米安的正电子变量特征相比,以下内容相形见绌,但这是我在思考这个问题时的想法。

有人大概可以实现类似以下编译指示的东西:

use PS;
say $text;
BEGIN $text = 'abc';

PS将在词法上应用no strict,此外还要求避免编译时错误:

  • 自动声明的变量/常量必须与BEGININIT相位器中的后声明匹配;

  • 如果变量/常量的首次使用(文本方式)不是绑定或赋值,则声明必须包括初始化。

最新更新