错误:"无法在标量赋值中复制到ARRAY"

时间:2016-03-04 06:04:51

标签: perl coderef

情况是我在sub尝试使用来电者$a$b,类似于sort。大部分时间它都可以工作,但是在运行单元测试时,我注意到在一个案例中,在一个软件包中,它没有用。我使用caller获取调用者的包,然后设置他们的$a$b,如下面的简化演示所示。只需在我发现它的包中调用此whatever函数,就会发生 的问题。

sub whatever {         # defined in main package
  my $pkg = caller;
  no strict 'refs';
  ${"${pkg}::a"} = "";
  ${"${pkg}::b"} = "";
}

我尝试创建一个最小的包/类来重现问题,但问题不会在这种情况下发生,但我在下面发布我的尝试作为一般背景的指示:

package WhateverClass {
    sub new {
        my ($class, $something, $something2) = @_;
        my $this = {};
        bless $this, $class;
        $this->{something_} = $something;
        $this->{something2_} = $something2;
        return $this;
    }
    sub test { # bug reproduction
        main::whatever();
    }
}

my $obj = WhateverClass->new(1.0, 2.0);
$obj->test;

错误消息是,

Error: "Cannot copy to ARRAY in scalar assignment"

它由确切的行触发:

${"${pkg}::a"} = "";

将其缩小到这个"无论什么"函数,我尝试在该赋值的右侧放置各种东西,包括arrayrefs,数组,如图所示的字符串,数字以及undef。它接受的只是undef,整数值和浮点值。它不接受arrayrefs,hashrefs或字符串。在我的情况下,在暴露此问题的原始代码中,传递的内容是对象引用或祝福的hashrefs,并且这些分配失败,因为如果任何hashref或arrayref赋值失败,则会失败。

更奇怪的是,在Perl调试器下,问题不会发生,但如果我正常运行则会发生。

谷歌搜索这个没有找到与这个确切错误匹配的东西,而且甚至很少接近。所以第一个问题是这个错误信息甚至意味着什么?第二个问题显然是如何向前发展。

我在Linux上使用Perl 5.20.3,但我也在Windows机器上尝试了最新的5.22并且看到了相同的行为。

1 个答案:

答案 0 :(得分:0)

我发现我的修复程序与这样一个事实有关,即使用此代码看到任何问题的唯一位置的包在其出现问题之前的生命周期中的某一点{{1} } List::MoreUtils。一些但不是全部的问题行为在调试器中是可重现的,我追踪了“错误”行为开始的地方,并且在调用pairwise之后。我改变了这个调用,使用了我自己的一个基本相同的例程,问题完全消失了(感谢上帝)。这是一个非常令人不安的问题。正如@ikegami所指出的那样,“有缺陷的XS代码”可能就是问题所在,我的例程就是纯粹的Perl而没有任何XS代码。