Perl中<<'m'=~m>>语法是什么意思?

82

我理解Perl有很多不寻常的语法,但最近在工作中遇到了一段让我困惑的代码片段。请问是否有人能够向我解释一下它的含义:

<<'m'=~m>>
print $a unless $b;
return;
m
;

看起来像是HEREDOC语法,但不是我见过的任何形式。


2
可能是理解奇怪的Perl多行注释机制的重复问题。 - Gilles 'SO- stop being evil'
1
您可以在此处访问Perl秘密运算符和常量列表:http://search.cpan.org/dist/perlsecret/lib/perlsecret.pod。 - aloisdg
2个回答

125

这个秘密的语法被称为华丽双刃剑,通常表示为:

<<m=~m>>

Comments here

m
;

这是一个用于多行注释的hack,利用heredoc语法和匹配运算符(=~),使用>作为分隔符。
注意,由于斜杠/未被用作匹配分隔符,所以需要使用'm'运算符。例如,$my_var =~ /test/相当于$my_var =~ m>test>,而$my_var =~ >test>将无效。
请注意,您代码片段中第一个m字符被单引号括起来,这意味着$a$b变量不会被插值。如果省略这些引号(如我的提供的代码示例),perl将自动在结束标记后添加双引号,并且任何后续变量都将被插值。如果$a$b未再定义并且您正在使用use warnings;,则会出现问题。
为了使上面的华丽双刃示例更易于理解(但仍不建议使用),我们可以编写:
<<"END" =~ //

Comments here

END
;

注意,=~ //是多余的,因此这等同于:
<<"END";

Comments here

END

这只是在无上下文情况下使用标准的heredoc语法。我不建议在生产代码中使用它,因为将字符串放在无上下文环境中可能会导致问题。此外,即使对于最有经验的Perl程序员来说,这段代码也很难理解和维护!如果您想创建正确的多行注释,则建议使用如此处所述的pod。如何在Perl中输入多行注释?希望这能澄清问题。

24

运行B::Deparse会有很大帮助,以便理解Perl如何处理那段代码(假设它在“test.pl”文件中):

perl -MO=Deparse  test.pl 

展示给我们:

"print \$a unless \$b;\nreturn;\n" =~ //;
test.pl syntax OK

所以,正如您所看到的,perl 正试图将一个空的正则表达式与这个字符串匹配:"print \$a unless \$b;\nreturn;\n"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接