使用此脚本
use warnings;
use strict;
my $w = rand * 4;
口译员给了我这个警告:Argument "*main::4" isn't numeric in rand
。我不明白为什么会这样,并希望有人解释这里发生的事情。
当然,我可以使用rand() * 4
或4 * rand
使警告消失。
答案 0 :(得分:3)
在perl中,*
是称为typeglob的怪异类型的印记。 typeglob是由该名称标识的所有对象的符号表条目 - 例如,如果您要运行:
$a = 1;
*b = *a;
print $b;
你会得到1
。你可以用typeglobs做一些其他的事情,但是没有一个是非常有用或相关的。
Perl解析器从左到右工作。它看到您尝试将rand * 4
的值分配给my $w
。它将rand
标识为内置函数的名称,并开始查找参数。然后,它会看到*
,并将其解释为sigil而不是运算符。它成功地识别了在语法上是合法标识符的参数(*4
),就解释器而言,它已经完成了对该行的解析。直到我们实际调用内置rand
时,解释器才会发现typeglob不是一个合法的参数。
所以,这是因为:
rand
是否有合法参数,如果没有,则调用它而不带参数*4
是变量的合法名称rand
不希望传入一个typeglob 您可以通过以下方式解决此问题:
4 * rand
rand()
,不带参数答案 1 :(得分:1)
Perl将*4
解释为rand()
的参数,更准确地说是*main::4
,它是包含变量的globtype。
perl -we 'my $w = rand (*::4);'
相同的输出:
Argument "*main::4" isn't numeric in rand
Deparse对这些等价物有相同的想法,
perl -MO=Deparse -e 'my $w = rand *4;'
my $w = rand *4;
perl -MO=Deparse -e 'my $w = rand *main::4;'
my $w = rand *4;