in reply to weird subroutine behavior

I'm not sure this is a solution, but it's at least part of the problem. See here:

foreach my $str (sort {($substrings{$b}[1]-$substrings{$b}[0]) <=> + ($substrings{$a}[1]-$substrings{$a}[0]) || $substrings{$a}[0] <=> $s +ubstrings{$b}[0]} keys %substrings){

The conditions you give to sort do not differentiate every element. If I go to the end of that block and add "|| warn 'identical item'", this will tell me if there's some pair in the list that the block can't distinguish. Running that, I see that sort encounters such pairs several times. I don't fully understand everything you're doing here, but I would guess that the elements that the condition sees as identical aren't really identical.

So what I think is happening is that on different runs, that sort is sorting differently. I'm not sure why running it once or twice makes a difference, but I suspect it's just perl's internals. For example, maybe keys is giving you the same things in different order, and sort preserves that order.

Anyway, if I add "|| $b cmp $a" in there, it seems to act the way you want. Since you're sorting keys, and they're unique, you can be pretty sure this will offer consistent behavior. The new full line is:

foreach my $str (sort {($substrings{$b}[1]-$substrings{$b}[0]) <=> + ($substrings{$a}[1]-$substrings{$a}[0]) || $substrings{$a}[0] <=> $s +ubstrings{$b}[0] || $b cmp $a } keys %substrings){

Replies are listed 'Best First'.
Re^2: weird subroutine behavior
by flaviusm (Acolyte) on Apr 02, 2008 at 16:21 UTC

    Thanks a lot. If I change the "sort" to the proposed version, the subroutine works as expected

    Since, all of you were thinking about what I was trying to accomplish with this "sort", this is what I tried to do:

    having:
    $substrings[0]
    $substrings[1]
    $substrings[2]
    $substrings[3]

    I wanted to sort by two keys:
    1. Descending - by the difference of $substrings[1] and $substrings[0]
    2. Ascending - by $substrings[0]

    Please let me know if you can lead me to a better and safer version of "sort".