0

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.

user62177541
  • 368
  • 3
  • 14
  • 3
    Can you provide a (minimal) complete program that exhibits the error? – hobbs Mar 04 '16 at 06:11
  • I'd like to, but as I said it happens in this one package and not all. I can't post the entire package, but calling the above function in that package is sufficient to trigger the error. The package has nothing in it named "a", variable, method, or otherwise and has no global or package level data at all. The package represents a class, with bless, so an instance method is called on the package, then that method calls the above function and then the error occurs. I will try to create a special package just to reproduce the error for you, but I may not have luck doing that. – user62177541 Mar 04 '16 at 13:15
  • I did just try to create a minimal example, a second class/package that invokes this "whatever" global function just like the other one, and the error does not occur. As I say it generally works. As I said in the debugger it also works. Any suggestions for tracking it even as well appreciated. – user62177541 Mar 04 '16 at 13:32
  • ...Also the `whatever` function shown above is defined in the `main` package. The whatever function is just an ordinary function, not a method. – user62177541 Mar 04 '16 at 13:40
  • Sounds like some buggy XS code or Perl internals left things in a illegal state. – ikegami Mar 04 '16 at 15:39
  • Do you get the same behavior if you use other names than `$a` and `$b`? – Calle Dybedahl Mar 04 '16 at 16:15
  • @ikegami I think you turned out to be right. I was looking through trying to locate where it was coming from and it looks like the origin of this problem is the fact that in one place inside this package I used `pairwise`, as in `List::MoreUtils` `pairwise`. I replaced that with a routine I have that does something similar and the problem is gone. @Calle, no I cannot freely choose the name as there aren't that many special variables like these, just `$_`, `$a`, and `$b`. – user62177541 Mar 05 '16 at 00:41

1 Answers1

0

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.

user62177541
  • 368
  • 3
  • 14