On Sat Aug 10 03:56:55 2013, SREZIC wrote:
Show quoted text> The problem can be reproduced with the following script:
>
> use Class::Prototyped qw(:NEW_MAIN);
> $p10 = new([qw(b FIELD autoload 1 wantarray 1)] => sub { });
> warn join("\n", @{ ($p10->reflect->getSlots)[0] }), "\n";
>
> With perl 5.18.0, the output is either
>
> b
> FIELD
> wantarray
> 1
> autoload
> 1
>
> or
>
> b
> FIELD
> autoload
> 1
> wantarray
> 1
>
> that is, autoload and wantarray may be swapped.
>
> The problem is caused by getSlot and getSlots creating a data
> structure like this:
>
> [$slot, $type, %$attribs]
>
> Because of hash randomization, the order of the keys in %$attribs is
> random. And because the hash is interpolated into an array, there's no
> way to fix this afterwards (e.g. using Sortkeys=1 or Test::Deep or
> so).
>
> I see the following possible solutions:
>
> * In getSlot and getSlots, make sure that the interpolation is done
> with a sorted hash, i.e. do something like this (untested): [$slot,
> $type, (map { ($_=>$attribs->{$_}) } sort keys %$attribs)]
>
> * In the autoload.t test, do the comparison "manually" for the failing
> test, e.g. checking element by element.
>
> * getSlot and getSlots have the "rotated" format option, which looks
> like it's returning something which may be compared, as the %$attribs
> hash stays a hash.
First, let me offer my abject apologies for neglecting this over the last few months. For better or worse, I've been pivoting to Ruby and my Perl skills are definitely getting rusty. My module releasing skills weren't much to begin with, and started atrophying years ago, which definitely contributed to my fear of attacking this.
Second, let me thank Slaven Rezic for the in depth investigation and handing me an almost complete solution! I'll take what's behind door three! That has the advantage of no changes to the code itself, just to the test suite, which reduces the chance that I'll introduce an issue. Since the attribs hash wasn't sorted to begin with (it's just that we were assuming in the test suite that identical hashes would sort identically), I doubt that leaving the code itself as is will cause issues in production code.
With that in mind, I've gone through the test suite and changed almost all of the calls to getSlots to use rotated as the output format. The two exceptions are in situations where there should never be more than one key in the hash. I've also verified that all of the calls to getSlot are either in scalar contexts (where only the value is returned) or in scenarios where the will never be more than one key in the hash.
I'd like to release, but I'm not particularly excited about trying to get bleadperl compiled for my box. Is there any chance that if I package up the directory, there might be someone to whom I could send it for verification that it tests fine against 5.18? It's testing fine against 5.16, and the only changes are to the t directory (and versions numbers).
Thanks!
I have to say it never ceases to amaze me that code that does this much symbol table manipulation and generally evil envelope boundary pushing has made it from 5.10 through 5.12, 5.14, and 5.16 without any updates!
--Toby Ovod-Everett