我想用我的程序将文字分配给文件末尾的一些变量,但是要先使用这些变量。我提出的唯一方法是:
my $text;
say $text;
BEGIN {
$text = "abc";
}
是否有更好/更惯用的方式?
答案 0 :(得分:5)
刚刚开始运作。
改为创建子程序:
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
断言对于给定的输入,函数"always produces the same output without any additional side effects":
say text; # "abc", interpreted as: say text()
say text ~ text; # "abcabc", interpreted as: say text() ~ text()
sub term:<text> is pure { "abc" };
答案 1 :(得分:3)
与Perl 5不同,在Perl 6中,BEGIN
不一定是块。但是,必须先查看词法定义才能使用它,因此BEGIN
块必须在say
之前完成。
BEGIN my $text = "abc";
say $text;
不确定这是否构成您问题的答案。
答案 2 :(得分:3)
首先,重温一下你的问题:
有哪些选项可以简洁地引用一个变量(或常量等),其初始化代码在同一源文件中显示得更深?
say foo;
sub foo { 'abc' }
当P6编译器解析具有 no identifier 的sigil时,它会检查它是否已经看到该标识符的声明。如果它没有,则它假定标识符对应于稍后将被声明为“listop”例程(其接受零个或多个参数)并继续前进的例程。 (如果它的假设结果是错误的,则编译失败。)
因此,您可以使用例程,就好像它们是Christopher Bottom's answer中描述的变量一样。
strict是一个"pragma",用于控制P6编译器在解析尚未声明的以sigil开头的变量/常量时的反应。
P6启动严格模式开启的程序。这意味着编译器将坚持预先声明任何sigil'd变量/常量。 (通过预先声明,我的意思是在使用变量/常量之前出现文本的显式声明。)
但是您可以编写use strict
或no 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
移相器在 compile -time(在my
声明之后运行,这也发生在编译时,但在say
之前,这是在运行时发生的。)
如果您想在运行时初始化变量/常量,请改用INIT
:
say my $text;
INIT {
$text = "abc";
}
INIT
代码在任何其他运行时代码之前运行,因此初始化仍然在say
执行之前发生。
ym
)变量鉴于对您的问题的字面解释,“positronic”或ym
变量将是另一种解决方案。 (这个功能不是内置的。我之所以包括它,主要是因为我在回答这个问题之后遇到它并认为它属于这里,至少对娱乐价值而言。)
这种变量的初始化和计算从 last 语句开始使用它,并相对于代码的文本顺序向后发生。
这是几个疯狂的声音之一,但实际上工作和有用的概念,达米安“疯狂科学家”康威在他的2011年演讲中讨论在多个拓扑连接的量子 - 相对论并行空间时间的时间Quaquaversal虚拟纳米机器编程...制作简单!的。
以下是指向the bit where he focuses on these variables的链接。
(整个演示非常令人高兴,特别是如果你对物理学感兴趣;编程技巧;观看高度创造性的神童;和/或享受出色的演讲技巧和幽默。)
PS
pragma?就酷感而言,与我刚刚介绍的Damian的正电子变量特征相比,下面的情况相形见绌,但这是我在思考这个问题时的一个想法。
有人可能会实现类似下面的pragma:
use PS;
say $text;
BEGIN $text = 'abc';
此PS
将词法应用no strict
,另外还需要避免编译时错误:
自动声明的变量/常量必须与BEGIN
或INIT
移相器中的帖子声明匹配;
如果变量/常量的第一次使用(文本)不是绑定或赋值,则声明必须包括初始化。