
7stud
Enthusiast
Nov 23, 2009, 11:58 AM
Post #4 of 11
(2819 views)
|
Re: [TX_Jimmy] Misbehaving Hash Sorting
[In reply to]
|
Can't Post
|
|
Nice sleuthing. I never thought to try that.
I am not really good at programming. Whaat? I thought this was really clever:
my %hash; ... push (@{$hash{11082009}}, "$_"); I didn't know you could do that. That uses an undefined key, treats the undefined value returned by the undefined key as a reference, converts the reference to an array, then pushes a value into the array. Wow. Below is a simplified version of the problem if one of the experts wants to take a look. I think the explanation is going to involve closures. A closure means that when you define a function inside a block, the function gets a snapshot of all the variables that it can currently see--like the variables in the enclosing block and any global variables. Then when the function is executed, it refers to that snapshot for the values of those variables. Your by_count() function is getting its snapshot on the first run through the for loop; then for subsequent loops, the function is not redefined, and as a result the function is stuck with that original snapshot, which contains the first hash. When you execute the function by calling sort, it uses the values in its snapshot. Apparently, a block like you used to fix the problem does not create a closure, and therefore the block can see the current values in the loop.
use strict; use warnings; use 5.010; use Data::Dumper; my %h1 = ( 'a' => 5, 'b' => 8, 'c' => 1 ); my %h2 = ( 'a' => 200, 'b' => 150, 'c' => 100 ); my @AoH = (\%h1, \%h2); for my $h (@AoH) { my %hash = %$h; my @sorted_keys = sort by_val keys %hash; sub by_val { say "$a=$hash{$a}, $b=$hash{$b}"; $hash{$a} <=> $hash{$b} }; say "$_ = $hash{$_}" for @sorted_keys; say "=" x 20; } --output:-- c=1, a=5 c=1, b=8 b=8, a=5 c = 1 a = 5 b = 8 ==================== c=1, a=5 c=1, b=8 #comparisons here use first hashes values--not 100, 200, 150 b=8, a=5 c = 100 a = 200 b = 150 ====================
(This post was edited by 7stud on Nov 23, 2009, 12:38 PM)
|