繁体   English   中英

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

[英]Using a variable in a Perl 6 program before assigning to it

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

my $text;

say $text;

BEGIN {    
    $text = "abc";
}

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

只是去功能。

改为创建子程序:

say text();

sub text { "abc" }


更新(感谢 raiph!纳入您的反馈,包括使用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设为term ,这有效地使裸text行为与text()相同:

say text;        # "abc",    interpreted as: say text() 
say text ~ text; # "abcabc", interpreted as: say text() ~ text()

sub term:<text> { "abc" };

对于编译时优化和警告,我们还可以向其添加pure trait (感谢 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 编译器解析没有sigil标识符时,它会检查是否已经看到了该标识符的声明。 如果没有,则它假定标识符对应于稍后将被声明为“列表”例程(采用零个或多个参数)的例程并继续前进。 (如果它的假设被证明是错误的,则编译失败。)

因此,您可以使用例程,就好像它们是Christopher Bottom 的回答中所述的变量一样。

首次使用时自动声明变量

strict是一个“pragma” ,它控制 P6 编译器在解析以sigil开头的尚未声明的变量/常量时的反应。

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 } 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编译指示?

在冷静方面,与我刚刚介绍的 Damian 的正电子变量特征相比,以下内容相形见绌,但这是我在思考这个问题时的一个想法。

有人可能会实现类似以下 pragma 的东西:

use PS;

say $text;

BEGIN $text = 'abc';

这个PS将在词法上应用no strict并且另外要求,以避免编译时错误:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM