Error: "Cannot copy to ARRAY in scalar assignment"

112 Views Asked by At

The situation is that I am in a sub trying to use the caller's $a and $b, similar to what sort does. Most of the time it works, but while running unit tests I noticed in one case, inside one package, it did not work. I use caller to get the package of the caller and then set their $a and $b as shown in the following simplified demo. The problem does occur by simply calling this whatever function in the package where I discovered this.

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

I attempted to create a minimal package/class to reproduce the problem but the problem does not occur in this context, but I'm posting my attempt below anyway as an indication of the general context:

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;

The error message is,

Error: "Cannot copy to ARRAY in scalar assignment"

And it is triggered by the exact line:

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

Having narrowed it down to this "whatever" function, I tried putting a variety of things on the right side of that assignment, including arrayrefs, arrays, strings as shown, numbers, as well as undef. The ones that it accepts are only undef, integer values, and floating point values. It does not accept arrayrefs, hashrefs, or strings. In my case, in the original code that exposed this problem, the things being passed were object references, or blessed hashrefs, and those assignments fail as you'd expect if any hashref or arrayref assignment fails.

Even more strangely, under the Perl debugger the problem doesn't occur, but if I run normally it does.

Google searching for this turns up nothing matching this exact error and very little that is even close. So first question is what does this error message even mean? Second question is obviously how to move forward.

I'm using Perl 5.20.3 on Linux, but I also tried the latest 5.22 on a Windows machine and saw the same behavior.

1

There are 1 best solutions below

0
user62177541 On

I found the fix for me had to do with the fact that the package that was the only location where any problems were seen with use of this code had at one point in its lifetime prior to the problem appearing used List::MoreUtils pairwise. Some but not all of the problem behavior was reproducible in the debugger, and I tracked down where the "buggy" behavior began and it was after calling pairwise. I switched this call to use one of my own routines that does essentially the same thing and the problem is completely gone (thank God). This was quite a disturbing issue. As @ikegami noted, "buggy XS code" may be the problem, and my routine is pure Perl without any XS code.