简体   繁体   English

Perl-BEGIN非BEGIN块中的差异

[英]Perl - Differences in BEGIN an non-BEGIN block

I have a question regarding the const declaration in perl, and could not figure out the differences, please kindly point out what are the differences. 我对perl中的const声明有疑问,无法找出区别,请指出区别。

Below is the code: 下面是代码:

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

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

Now is the question, Why 现在的问题是,为什么

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

line must have a '&' in front of ITEM, But 行在ITEM前面必须有一个“&”,但是

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

line do not need to have a '&' in front of SIZE. 不需要在SIZE前面加上'&'。

And I know the BEGIN block is run at compile time. 而且我知道BEGIN块是在编译时运行的。

Because the BEGIN block is run at compile time, the compiler knows about the assignment to *SIZE , while the assignment to *ITEM hasn't happened yet. 由于BEGIN块是在编译时运行的,因此编译器知道*SIZE的分配,而*ITEM的分配尚未发生。

Because the compiler doesn't know about *ITEM , calls to ITEM are ambiguous, thus you must prefix it with an & . 由于编译器不了解*ITEM ,因此对ITEM调用是模棱两可的,因此必须在其前面加上& Otherwise, the compiler thinks it could be a "bare word" -- an unquoted string. 否则,编译器会认为这可能是“裸词”(unquoted string)。

If you use strict , the compile will assume that bare words are functions. 如果use strict ,则编译将假定裸词为函数。

use constant may also be a better way to declare constants, rather than doing it manually. use constant可能也是声明常量的一种更好的方法,而不是手动进行。

The code 代码

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

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

would get processed as follows if there was no error: 如果没有错误,将按以下方式进行处理:

  • Compile file. 编译文件。
    • Compile BEGIN block. 编译BEGIN块。
      • *SIZE = sub() { 2 };
    • Execute BEGIN block. 执行BEGIN块。
      • *SIZE = sub() { 2 };
    • Compile *ITEM = sub() { 10 }; 编译*ITEM = sub() { 10 };
    • Compile print 'size=', SIZE, "\\n"; 编译print 'size=', SIZE, "\\n";
    • Compile print 'item=', ITEM, "\\n"; 编译print'item print 'item=', ITEM, "\\n";
  • Execute file. 执行文件。
    • Execute *ITEM = sub() { 10 }; 执行*ITEM = sub() { 10 };
    • Execute print 'size=', SIZE, "\\n"; 执行print'size print 'size=', SIZE, "\\n";
    • Execute print 'item=', ITEM, "\\n"; 执行print'item print 'item=', ITEM, "\\n";

Note how print 'item=', ITEM, "\\n"; 注意如何print 'item=', ITEM, "\\n"; is compiled before the sub exists. 在子存在之前被编译。 If ITEM existed as a sub, that would be allowed. 如果ITEM作为子项目存在,那将是允许的。 But ITEM doesn't exist as a sub. 但是ITEM不作为子项存在。 In the absence of any other meaning, identifiers are bare words, and bare words are compiled into a string with the same value. 在没有其他含义的情况下,标识符是裸词,并且裸词被编译为具有相同值的字符串。

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

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

That is, unless you specifically ask Perl to do otherwise: 也就是说,除非您明确要求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.

That means you need to make ITEM look like a sub call. 这意味着您需要使ITEM看起来像一个子调用。

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

&ITEM also works, since & is the instruction to tell Perl to ignore prototypes. &ITEM也起作用,因为&是指示Perl忽略原型的指令。

The & prefix unambiguously means "this is a user-defined subroutine call coming up next". &前缀明确表示“这是下一个用户定义的子例程调用”。 You can omit it when you are using parens after your function name and your function name doesn't conflict with a built-in, or if you've declared/defined your function before you use it and the name doesn't conflict with a built-in. 您可以在函数名称之后使用parens并且函数名称与内置函数不冲突时,或者在使用函数之前声明/定义函数且名称与函数不冲突时,可以省略该函数。内置的。

Continuing read here 继续阅读这里

And check @Sean McMillan response. 并检查@Sean McMillan的回复。

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

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