in reply to Re^2: sort != sort
in thread sort != sort

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.

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

    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.

      The issue is, plain and simple, that @Notes is not being assigned to. Here's further evidence:

      I put the comparison checks back in and logged them this way:

      my $tmp1 = ""; @Notes = sort { $tmp1 .= $b->{terms}.$a->{terms}; my $r = $b->{terms} <=> $a->{terms}; $tmp1 .= "($r) "; return $r; } @Notes; my $tmp2 = ""; my @Sorted = sort { $tmp2 .= $b->{terms}.$a->{terms}; my $r = $b->{terms} <=> $a->{terms}; $tmp2 .= "($r) "; return $r; } @Notes; open(LOG,">/var/www/dump/tmp.txt"); print LOG "$tmp1\n$tmp2\n"; if ($tmp1 ne $tmp2) { print LOG "UNEQUAL" }

      $tmp1 does equal $tmp2, demonstrating that the sort operation occurred and occurred exactly the same way both times. I have also compared @Notes to a copy made before the operation, and it does not change. So again, the issue is, plain and simple, that @Notes is not being assigned to by sort @Notes. Sorry to be stubborn and assertive here, but what else is there to believe at that point? It is not that @Notes gets sorted wrongly, or that the one sort operation differs from the other.

      Of course, it's not a big deal as using the @Sorted array is fine and I can undef @Notes afterward. But if anyone thinks this looks like a bonified perl bug (first one I'll have found), and wants to give me some tips about how that could be verified using my existing code, I'd probably be willing to investigate. Otherwise...

      ps. I also did this using both "use sort _mergesort" and "use sort _quicksort". The quicksort does slightly fewer comparisons (kind of a surprise, considering the 11111111121111111112111 nature of the data) but otherwise the result is exactly the same.

        I'm not saying that what you're seeing is not a Perl bug. But your code is not yet convincing. You are fairly close though - you just need to show where @Notes is filled with data, and with what data. Note that Data::Dumper will output a string that is valid Perl code, so you can use Data::Dumper to get a canned version of the data that exhibits this behaviour.