参数" * main :: 4"在rand中不是数字

时间:2014-11-04 14:00:18

标签: perl

使用此脚本

use warnings;
use strict;

my $w = rand * 4;

口译员给了我这个警告:Argument "*main::4" isn't numeric in rand。我不明白为什么会这样,并希望有人解释这里发生的事情。

当然,我可以使用rand() * 44 * rand使警告消失。

2 个答案:

答案 0 :(得分:3)

在perl中,*是称为typeglob的怪异类型的印记。 typeglob是由该名称标识的所有对象的符号表条目 - 例如,如果您要运行:

$a = 1;
*b = *a;
print $b;

你会得到1。你可以用typeglobs做一些其他的事情,但是没有一个是非常有用或相关的。

Perl解析器从左到右工作。它看到您尝试将rand * 4的值分配给my $w。它将rand标识为内置函数的名称,并开始查找参数。然后,它会看到*,并将其解释为sigil而不是运算符。它成功地识别了在语法上是合法标识符的参数(*4),就解释器而言,它已经完成了对该行的解析。直到我们实际调用内置rand时,解释器才会发现typeglob不是一个合法的参数。

所以,这是因为:

  • Perl首先检查rand是否有合法参数,如果没有,则调用它而不带参数
  • 在Perl中,*4是变量的合法名称
  • Perl对参数没有严格的类型,因此词法分析器无法识别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;