Perl - BEGIN与非BEGIN块的差异

时间:2012-04-27 11:22:48

标签: perl

我对perl中的const声明有疑问, 请不要弄清楚差异,请好心 指出有什么不同。

以下是代码:

BEGIN {
  *SIZE = sub() { 2 };
}  
*ITEM = sub() { 10 };

print 'size=', SIZE, "\n";
print 'item=', &ITEM, "\n";

现在是问题,   为什么

  print 'item=', &ITEM, "\n";

行必须有'&'在ITEM面前   但是

  print 'size=', SIZE, "\n";   

行不需要'&'在SIZE面前。

我知道BEGIN块在编译时运行。

3 个答案:

答案 0 :(得分:7)

因为BEGIN块是在编译时运行的,所以编译器知道*SIZE的赋值,而*ITEM的赋值尚未发生。

由于编译器不了解*ITEM,因此对ITEM的调用不明确,因此您必须在其前面添加&。否则,编译器认为它可能是一个“裸字” - 一个不带引号的字符串。

如果你use strict,编译将假定裸字是函数。

use constant也可能是一种更好的方式来声明常量,而不是手动执行。

答案 1 :(得分:2)

代码

BEGIN {
  *SIZE = sub() { 2 };
}  
*ITEM = sub() { 10 };

print 'size=', SIZE, "\n";
print 'item=', ITEM, "\n";
如果没有错误,

将按如下方式处理:

  • 编译文件。
    • 编译BEGIN块。
      • *SIZE = sub() { 2 };
    • 执行BEGIN阻止。
      • *SIZE = sub() { 2 };
    • 编译*ITEM = sub() { 10 };
    • 编译print 'size=', SIZE, "\n";
    • 汇编print 'item=', ITEM, "\n";
  • 执行文件。
    • 执行*ITEM = sub() { 10 };
    • 执行print 'size=', SIZE, "\n";
    • 执行print 'item=', ITEM, "\n";

注意在子存在之前如何编译print 'item=', ITEM, "\n";。如果ITEM作为子存在,那将是允许的。但是ITEM不存在作为子。在没有任何其他含义的情况下,标识符是裸字,裸字被编译成具有相同值的字符串。

>perl -E"my $x = ITEM; say $x;"
ITEM

>perl -E"my $x = 'ITEM'; say $x;"
ITEM

也就是说,除非你特别要求Perl做其他事情:

>perl -E"use strict; my $x = ITEM; say $x;"
Bareword "ITEM" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

这意味着您需要使ITEM看起来像子调用。

print 'item=', ITEM(), "\n";

&ITEM也有效,因为&是告诉Perl忽略原型的指令。

答案 2 :(得分:1)

&前缀明确地表示“这是用户定义的子程序调用接下来”。当您在函数名后使用parens并且函数名与内置函数不冲突,或者在使用它之前声明/定义了函数并且名称与a不冲突时,可以省略它。内置。

Continuing read here

并查看@Sean McMillan回复。