Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Sorted tied hash wierdness

by genecutl (Beadle)
on Nov 18, 2003 at 23:45 UTC ( [id://308188]=perlquestion: print w/replies, xml ) Need Help??

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

I just got done writing and debugging some code which made use of a sorted tied hash using DB_File BTREE. I was getting weird results which I was able to track down to my custom sorting algorithm. Shown below is the pared-down code containing both the working and non-working versions of the sorting algorithm:
use Fcntl; use DB_File; my $db_file = '/tmp/db_file'; unlink $db_file if -e $db_file; my $btree_info = new DB_File::BTREEINFO; $btree_info->{'flags'} = R_DUP; my $comparison_type = shift @ARGV; if (! $comparison_type) { # this method works $btree_info->{'compare'} = sub { my($a,$b) = @_; $a <=> $b }; } else { # this method does not work $btree_info->{'compare'} = sub { $_->[0] <=> $_->[1] }; } $tied_hash_obj = tie( %tied_hash, 'DB_File', $db_file, O_RDWR|O_CREAT, + 0640, $btree_info ) or die "Can't tie tied_hash to $db_file: $!"; for ( 0 .. 20) { $tied_hash{rand(100)} = ++$i; } my ($status, $k, $v); for ( $status = $tied_hash_obj->seq($k, $v, R_FIRST); $status == 0; $status = $tied_hash_obj->seq($k,$v, R_NEXT) ) { push @vals_sorted_by_keys, $v; push @sorted_keys, $k; } print join("\n", @vals_sorted_by_keys),"\n********\n"; print join("\n", @sorted_keys),"\n";
Comparing $_->[0] and $_>[1] directly, leads to all the keys coming out equal to the very first key. Saving $_>[0] and $_>[1] to temporary variables eliminates this problem. Can someone explain this?

Replies are listed 'Best First'.
Re: Sorted tied hash wierdness
by Chmrr (Vicar) on Nov 18, 2003 at 23:49 UTC

    You're getting too reference-happy. $_->[0] isn't the same as $_[0] -- the former treats $_ as an array ref, and takes the 0th element of that, while the second takes the 0th element of the @_ array. In this case, it's the latter you want. Change sub { $_->[0] <=> $_->[1] } to sub { $_[0] <=> $_[1] } and you'll have more luck.

    perl -pe '"I lo*`+$^X$\"$]!$/"=~m%(.*)%s;$_=$1;y^`+*^e v^#$&V"+@( NO CARRIER'

      You're absolutely right. Don't you hate it when you waste time on something that should be completely obvious? Thanks!
Re: Sorted tied hash wierdness
by Roger (Parson) on Nov 19, 2003 at 00:03 UTC
    You can change the line:
    $_->[0] <=> $_->[1]
    to
    $_[0] <=> $_[1]
    or
    @_->[0] <=> @_->[1]
    and even insanely to
    @{[shift]}->[0] <=> @{[shift]}->[0]
    And it will work.

    The last last solution is highly perl implementation dependent, it will not work if the order of evaluation changes in the future. I came up with it just to see if I could compare two shift's directly for fun. And yes it works. :)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (2)
As of 2024-04-26 04:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found