Perl -常量的用法不明确,解析为-&;常数()

Perl -常量的用法不明确,解析为-&;常数(),perl,Perl,我试图在Perl脚本中将幻数声明为常量,如perlsub中所述。但是,我收到警告: $ cat foo.perl use warnings ; use strict ; sub CONSTANT() { 5 } print 7-CONSTANT,"\n" ; $ perl foo.perl Ambiguous use of -CONSTANT resolved as -&CONSTANT() at foo.perl line 3. 2 $ 如果我在减号和常量之间插入空格,警告就会消失

我试图在Perl脚本中将幻数声明为常量,如perlsub中所述。但是,我收到警告:

$ cat foo.perl
use warnings ; use strict ;
sub CONSTANT() { 5 }
print 7-CONSTANT,"\n" ;
$ perl foo.perl
Ambiguous use of -CONSTANT resolved as -&CONSTANT() at foo.perl line 3.
2
$ 
如果我在减号和
常量之间插入空格,警告就会消失。它使表达比我想要的更通俗易懂,但它确实有效

不过,我很好奇:它在警告我什么?我不知道还有什么方法可以解析它


(来自Debian“挤压”的Perl 5.10.1)。

mpapec的回答很有帮助地引用了(我不知道),但引用了错误的诊断。我真正得到的是

不明确使用-%s解析为-&%s()

(模棱两可)您编写了类似-foo的东西,可能是字符串“-foo”,或者对函数foo的调用被否定。如果你指的是字符串,就写“-foo”。如果您指的是函数调用,请编写-foo()

所以很明显,关键是
-常量
是一个有效的裸字。我不知道他们可以从破折号开始

我仍然不明白为什么会在这里给出警告,因为(a)我使用的是
严格subs
,所以显然我不会故意乱丢裸字,(b)即使我是,这个位置的裸字或字符串无论如何都会是语法错误

Edit:正如托宾克(或多或少)指出的那样,
-常量本身并不是一个空字,但
严格的subs
仍然允许在一元减号运算符之后使用空字。显然,lexer没有足够的上下文意识,不允许在此上下文中将
-CONSTANT
解析为一元负号


我仍然觉得很奇怪——有人会认为没有参数的sub原型的效果应该是我故意放弃使用该名称作为裸字,不管它是作为一元减号的操作数还是在不同的上下文中。

首先,一些背景。让我们看一下下面的内容:

$_ = -foo;
-foo
是字符串文字[1]

除非已声明名为
foo
的子项

$ perl -Mstrict -wE'sub foo { 123 } say -foo;'
Ambiguous use of -foo resolved as -&foo() at -e line 1.
-123
现在回到你的问题上来。警告是错误的。一个术语(
7
)后面不能跟另一个术语,因此
-
不能是字符串文字或一元减号运算符的开头。它必须是减法运算符,因此没有歧义

此警告仍在5.20.0[2]中发布。我已提出申请


  • 看,妈妈!没有报价

    system(grep => ( -R, $pat, $qfn ));
    
  • 好吧,5.20.0还没有发布,但在发布之前,我们处于代码冻结状态。这不会在5.20.0中修复


  • 可能是常数的更好替代品。@ikegami,这不会让Damian不高兴吗?:-)关于(a),以破折号开头的单词是允许的,即使在有严格sub的范围内也是允许的。它记录在。我个人最喜欢的理论是,这最初是由于解析文件测试操作符(
    -f
    -d
    ,等等)而导致的错误,但被发现是有用的,因此成为了一个文档化的功能。关于(b),是的
    7“-foo”
    将是一个语法错误,因为两个相邻的值之间需要一个运算符。这就是为什么在本例中,潜在的歧义
    -foo
    被解析为
    -&foo()
    ,而不是
    “-foo”
    。然而,还有一些情况下,
    -foo
    更加模糊,例如
    bar(-foo)
    ,因此当遇到这种模糊时,Perl总是警告您注意这种模糊性。@Tobynk:实际上perlop似乎记录的是,应用于普通单词的一元减号将在字符串前面加上减号。因此,至少根据文档,
    -foo
    将解析为
    -'foo'
    ,并计算为字符串
    “-foo”
    ;它适用于
    $a=“foo”;print-$a
    也是。我不确定这是原因还是结果,但可以通过散列参数化的子例程通常使用以破折号开头的参数名。请参见,例如:
    print$q->header(-type=>“image/gif”)
    。这就意味着以破折号开头的单词会得到一些特殊的处理。好极了,那么
    =>
    实际上是在原始词汇级别自动引用,而不考虑语法?看起来是这样的:
    使用严格;打印“abc”,length def=>”\n
    打印
    abc3
    ,毫无怨言…@Henning Makholm,一个后跟
    =>
    的裸字被自动引用。是的,这是在词汇层面上完成的。(还有哪里?!)我不知道你所说的“不考虑语法”是什么意思“.x@ikegami:我一直理解这意味着,在解析之后,如果
    =>
    左侧的整个表达式只包含一个裸字,那么来自“strict subs”的错误将被抑制。一个人的生活和学习…@Henning Makholm,解析后没有空话或
    =>
    。解析的全部目的是赋予符号意义。嗯,你链接的bug报告似乎并没有说明问题所在。它是
    say-foo
    ,在减号/破折号前面没有任何术语。
    system(grep => ( -R, $pat, $qfn ));