Harry Putnam wrote:
I have an example from Shawn C. from another thread, presented here
out of context. The code does just what he meant it to do.
It inverts a hash.
I'm trying to understand what is going on inside the sub function
`invert()'.
------- --------- ---=--- --------- --------
my %hash = (
'./b/fb' => 'fb',
'./b/c/fd' => 'fd',
'./b/l/c/f2' => 'f2',
'./b/g/f/r/fc' => 'fc',
'./b/g/h/r/fb' => 'fb'
);
## %hash is sent to an inversion sub function
my %inv_hash = invert( \%hash );
sub invert {
my $h = shift @_;
my %inv = ();
while( my ( $k, $v ) = each %{ $h } ){
push @{ $inv{$v} }, $k;
}
return %inv;
}
------- --------- ---=--- --------- --------
What is actually being sent at
my %inverse_hash = invert( \%hash );
A reference to the hash %hash is being sent.
Inside the sub function:
incoming data is seen as array (@_)
What happened to the hash? Is it flattened or what?
It's still there. The array @_ has a reference to the hash as its first
value.
What is actually being shifted off here
my $h = shift @_; (Just one element?)
The reference is stored in the variable $h.
Here it appears $h is expected to have two parts.
So apparently sending \%hash to this sub function has flattened it
into an array where each elements is made up of the Key and value
of the former array...
while( my ( $k, $v ) = each %{ $h } ){
The function each only works on hashes. $h is dereference with %{ $h }
See `perldoc -f each`
It appears above that $h has all the former parts of the hash
else how can it be looped?
but at `my $h = shift @_;'
It looks like only one is shifted.
Yes, only one argument is sent to the function, the reference to the hash.
Then at:
push @{ $inv{$v} }, $k;
It appears the parts to an array are again flattened into
an array
If $inv{$v} does not exists, then this statement create an empty,
anonymous array and pushes the value of $k onto it. If $inv{$v} exists,
it must be a reference to an array or this will cause a fatal error.
Then here:
return %inv;
It magically becomes a hash again only upside down.
and of course same name keys are zapped.
%inv_hash is now:
'fc' => './b/g/f/r/fc'
'f2' => './b/l/c/f2'
'fb' => './b/fb' (might be './b/g/h/r/fb'. One was deleted)
'fd' => './b/c/fd'
or seen through Data::Dumper:
Key fc | value ARRAY(0x8bb29c0)
Key f2 | value ARRAY(0x8bb2a60)
Key fb | value ARRAY(0x8bb29f0)
Key fd | value ARRAY(0x8bb2a20)
There is a lot happening in there... but I'm not following how it
happens.
my %inv_hash = invert( \%hash );
print '%inv_hash: ', Dumper \%inv_hash;
This will output:
%inv_hash: $VAR1 = {
'f2' => [
'./b/l/c/f2'
],
'fb' => [
'./b/fb',
'./b/g/h/r/fb'
],
'fc' => [
'./b/g/f/r/fc'
],
'fd' => [
'./b/c/fd'
]
};
Note that both values for fb are preserved.
--
Just my 0.00000002 million dollars worth,
Shawn
Programming is as much about organization and communication
as it is about coding.
I like Perl; it's the only language where you can bless your
thingy.
Eliminate software piracy: use only FLOSS.
--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/