Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

sort AoH buggy?

by LanX (Saint)
on Dec 09, 2021 at 15:49 UTC ( [id://11139505]=perlquestion: print w/replies, xml ) Need Help??

LanX has asked for the wisdom of the Perl Monks concerning the following question:

This is the weirdest bug and I'm totally confused.

I created a buggy function but my tests miraculously passed none the less.

I narrowed it down to this demo where sort is magically expanding stringified hashrefs like "HASH(0x253f0c8)" ...

(see <--- WTF? in output)

Could someone please explain the difference between sort AoH and sort {$a cmp $b } AoH here

use v5.12; use warnings; use Data::Dump; my $AoH; debug_loop_join();exit; sub loop_join { my %H; $H{$_} = () for @$AoH; return keys %H; } sub debug_loop_join { $AoH = create_data (.2, 10); ddx [ loop_join ($AoH) ]; ddx [ sort loop_join ($AoH) ]; ddx [ sort {$a cmp $b } loop_join ($AoH) ]; } sub create_data { my ($density, $records) = @_; my @AoH; push @AoH, {map { rand 100 <= $density ? ( $_ => $_ ) : () } "A" . +. "ZZ"} for 1 .. $records; return \@AoH; }
OUTPUT:
# sort_hash_bug.pl:18: [ # "HASH(0x253f0c8)", # "HASH(0x25350c8)", # "HASH(0x268aa20)", # "HASH(0xeea828)", # "HASH(0x2535548)", # "HASH(0x2535128)", # "HASH(0x268aab0)", # "HASH(0x2535260)", # "HASH(0x268a840)", # "HASH(0x268a918)", # ] # sort_hash_bug.pl:19: [ # <--- +WTF? # [ # {}, # { AZ => "AZ", EM => "EM", RY => "RY" }, # {}, # { GT => "GT", JR => "JR", RZ => "RZ" }, # { HY => "HY" }, # { HT => "HT" }, # { VH => "VH", WU => "WU" }, # { GR => "GR", HH => "HH", HM => "HM", JC => "JC", WJ => "WJ" }, # {}, # { BK => "BK", UH => "UH", XX => "XX", ZN => "ZN" }, # ], # ] # sort_hash_bug.pl:20: [ # "HASH(0x25350c8)", # "HASH(0x2535128)", # "HASH(0x2535260)", # "HASH(0x2535548)", # "HASH(0x253f0c8)", # "HASH(0x268a840)", # "HASH(0x268a918)", # "HASH(0x268aa20)", # "HASH(0x268aab0)", # "HASH(0xeea828)", # ]

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re: sort AoH buggy?
by choroba (Cardinal) on Dec 09, 2021 at 16:05 UTC
    Documented in sort. One of the worst mishaps in Perl.
    Warning: syntactical care is required when sorting the list returned from a function. If you want to sort the list returned by the function call find_records(@key), you can use:
    my @contact = sort { $a cmp $b } find_records @key; my @contact = sort +find_records(@key); my @contact = sort &find_records(@key); my @contact = sort(find_records(@key));
    If instead you want to sort the array @key with the comparison routine find_records() then you can use:
    my @contact = sort { find_records() } @key; my @contact = sort find_records(@key); my @contact = sort(find_records @key); my @contact = sort(find_records (@key));
    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      Thanks I get it.

      Sort sees the function call actually as a comparison routine.

      Tricky ...

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      honestly the difference by whitespace is horrible, I got bitten again...

      my @contact = sort(find_records(@key)); #vs my @contact = sort(find_records (@key));

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      Well... I never ever see comparison routines in the form

      • sort my_comp LIST

      used.

      If you really need a special sort it's normally far easier to write

      • sub my_sort { sort {...} @_ }

      They are useful when combining them in multi_sorts with other comparisons, like ...

      • sort { my_comp or $a cmp $b } LIST

      ... , but in this case you are always free to surround single my_comps with curlies.

      • sort { my_comp } LIST

      I'd say this syntax should be deprecated.

      (Unless someone could show me useful applications)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        I'd say this syntax should be deprecated.

        I assume you're referring to the sort my_comp LIST syntax. Otherwise, you're just ... wrong.

        But what would be the point of deprecating? What harm does it cause? Deprecating it would only serve to break the few instances of code out there that use it.

        I reckon we are the only monastery ever to have a dungeon staffed with 16,000 zombies.
      A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11139505]
Approved by Gavin
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (2)
As of 2024-04-25 20:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found