in reply to sort != sort

WRT replicating it: I also tried prior to the post and cannot, I was hoping there might be an obtuse reason someone is aware of, since I am positive about the data, etc. Ie, this is not a coding error. Here's exactly the way I am verifying the issue right now:

if ($#Terms > 0) { print "HERE\n"; # to confirm this takes place; @Notes = sort { $b->{terms} <=> $a->{terms} } @Notes; } my @Sorted = sort { $b->{terms} <=> $a->{terms} } @Notes; print "$#Notes $#Sorted\n"; for (my $i = 0; $i<=$#Notes; $i++) { print $Notes[$i]->{terms}.$Sorted[$i]->{terms}."\n"; }

The output begins:

HERE 1008 1008 12 12 12 12 12 [..etc: nb, there is never anything other than 1 or 2]

As if "@Notes" were scoped locally in the if block. Again, this not normal behaviour nor can I replicate it in a simpler script. However, I do not see possibility of bad data affecting the above logic (please tell me specifically how you think it could, if you do). These are two versions of the same sort operation on the same array.

Interestingly, if I make a single change, by moving "my @Sorted = sort" to before the if block instead of after it (making it the first line in the above code) both arrays are the same.

I've done this and other tests numerous times here purely for this purpose, there is no possibility of me having "forgotten a change in the middle". But I'm a sceptic too: if you think this is impossible and I'm lying, I don't blame you ;)

Replies are listed 'Best First'.
Re^2: sort != sort
by Corion (Patriarch) on Oct 25, 2010 at 17:28 UTC

    You could start by telling us the version(s) of Perl you've tested this against, by showing us what objects live in @Objs, and maybe dumping 5 of these objects. Reduce your dataset and code until the problem goes away, then put back in the last thing you took out.

    It is highly unlikely that this is a bug in Perl, and far more likely that it is a bug in your code (or data), but it's very hard for us to guess about your code, as you don't show it.

      v5.10.0 built for x86_64-linux-thread-multi

      I would do that, except this is a fairly elaborate CGI which uses a database. The problem with removing code in this case is: what do I start removing? Random chunks? And if that worked, what would it mean? Eg, moving that sort line "fixes" the issue, but it does not provide me a clue as to why. It also very strongly implies to me that this is not my error and I will be wasting my time looking for a mistake that does not exist.

      Anyway, there are a zillion (other) ways the integrity of the code is tested, I was just curious about the bizarre behaviour. As demonstrated, all the data relevant to the sort operation is in order. I simply do not see anything that could be affecting this. If I were working in C, I could see some chance of an unrelated data structure causing an overwrite of something (a code segment, whatever) that would explain this, but AFAIK that is not possible in perl.

      The objects contain a lot of text, here's a dump with that edited out:

      $VAR1 = bless( { 'body' => 'SNIP', 'href' => '<a class="ntitle" href="SNIP">', 'date' => '29 February 2004 ', 'terms' => '1', 'title' => 'Michael Shrimpton on Dr. Kelly' }, 'PNSearch' ); $VAR1 = bless( { 'body' => 'SNIP', 'href' => '<a class="ntitle" href="SNIP">', 'date' => '9 September 2003 ', 'terms' => '2', 'title' => 'protester hit' }, 'PNSearch' );

      That's the first pair from the mismatched arrays (notice: 'terms' = 1 and 2). But I don't think there is anything to see with this.

      I'm not expecting anyone to make a big effort here -- if no one is aware of any possibilities, don't worry about it.

        The first thing to remove would be the CGI part. Replace the CGI with a simple script that just outputs the data. The next thing to remove would be the database query. Replace it with hardcoded values. Then remove some more subroutines that munge the data. Replace them with pre-munged data.

        After some work, you'll have reduced the problem to a small problem with well-defined input and output.