小写的“begin”是 Perl 关键字吗?

问题描述 投票:0回答:1

我在 Linux Debian 下运行 Perl 脚本版本 5.28,并带有一些实验性的“扩展”,并出现了奇怪的行为。在混合 Pascal-SQL-Perl 编程会话中,我错过了在 if-else 语句中输入小写

begin
而不是
else
(请参阅下面的测试代码),并得到了有效但出现故障的代码。

我知道大写的

BEGIN
关键字属于
BEGIN, UNITCHECK, CHECK, INIT and END
程序“程序运行前和程序运行后”组。但我使用了小写的
begin
变体,并且得到了有效的运行代码。在我看来,
begin {...}
块是在
if (...) {...}
表达式之后单独执行的,这会导致不必要的提前返回。

小写字母

begin
在 Perl 区分大小写的编程环境中有任何意义吗?

#!/usr/bin/perl
use v5.20;
use strict;
use warnings;
use feature qw(signatures);
no warnings 'once';
no warnings 'experimental';
no warnings 'experimental::signatures';

&if_exotic(1000);
&if_normal(1000);

# --------------------------------------
# Bad variant
# --------------------------------------
sub if_exotic($want) {

   if ($want>0) {
       print "BAD: ..running $want operations\n";
   } begin {
       print "BAD: ..nothing to do\n";
       return;
   }

    print "Do something $want times\n";
   
}

# --------------------------------------
# Good variant
# --------------------------------------
sub if_normal($want) {

   if ($want>0) {
       print "GOOD: ..running $want operations\n";
   } else {
       print "GOOD: ..nothing to do\n";
       return;
   }

    print "Do something $want times\n";
}

/usr/bin/perl "test-if-begin"
BAD: ..running 1000 operations
BAD: ..nothing to do
GOOD: ..running 1000 operations
Do something 1000 times
perl keyword
1个回答
9
投票

这是 Perl 的 间接对象表示法 的实际应用。

它允许(推荐的)语法

PackageName->method(args-list)

写成(a“discouraged”)

method PackageName arg-list

让我们将示例程序归结为

use warnings;
use strict;

indirect_notation_gotcha();

print "all good?\n";

sub indirect_notation_gotcha {

    anyword {
        print "This body stands for package name\n";
        return;                                      # runs before "anyword"
    }

}

通过间接对象语法,子内部的代码相当于

do {
    print "This body stands for package name\n";
    return
} -> anyword;

这是合法的语法,在运行时,

return
语句是“保存”它的,因为它永远不会达到不存在的
anyword

如果我们放弃

return

indirect_notation_gotcha();

print "all good?\n";

sub indirect_notation_gotcha {
    anyword {
        print "This body stands for package name\n";
    }
}

现在

anyword
is 已尝试,我们得到

这个body代表包名
无法通过包“1”找到对象方法“anyword”(也许您忘记加载“1”?)在...

如顶部链接所示,在较新的 Perls 中,这是一个可以禁用的功能(使用 v5.32+

 feature qw(indirect);  # v5.32+

在较新的 Perls 中,它在捆绑包中被禁用,

use v5.36; 

请参阅 perldelta 5.36.0

© www.soinside.com 2019 - 2024. All rights reserved.