using variables as hashes

R

Ravi Parimi

Hi ,

I have 4 hashes %aries, %taurus, %gemini, %leo, and each hash has
key=>value pairs like:

$aries{"beta"} = "192.168.2.10"
$aries{"gamma"} = "192.168.2.11"
and so on.

I would like to be able to print the contents of each hash without
explicity looping over the name of each hash.. I did something like:

foreach $foo qw /aries taurus gemini leo/ {
foreach $var (keys %foo) {
print "$var => $foo{$var}\n";
}
}

I know it doesnt make sense to do it this way, but is there a way such
that $foo in the first loop above can become a hash on each iteration
so that the inner loop works without any problem?

Thanks,
--ravi
 
U

Uri Guttman

RP> I have 4 hashes %aries, %taurus, %gemini, %leo, and each hash has
RP> key=>value pairs like:

RP> $aries{"beta"} = "192.168.2.10"
RP> $aries{"gamma"} = "192.168.2.11"
RP> and so on.

RP> I know it doesnt make sense to do it this way, but is there a way such
RP> that $foo in the first loop above can become a hash on each iteration
RP> so that the inner loop works without any problem?

use a hash of hashes. read perlreftut, perlref, perllol and perldsc.

if you need more help after reading those docs, feel free to ask for
clarifications.

uri
 
B

Ben Morrow

Ravi Parimi said:
I have 4 hashes %aries, %taurus, %gemini, %leo, and each hash has
key=>value pairs like:

$aries{"beta"} = "192.168.2.10"
$aries{"gamma"} = "192.168.2.11"
and so on.

I would like to be able to print the contents of each hash without
explicity looping over the name of each hash.. I did something like:

foreach $foo qw /aries taurus gemini leo/ {
foreach $var (keys %foo) {
print "$var => $foo{$var}\n";
}
}

I know it doesnt make sense to do it this way, but is there a way such
that $foo in the first loop above can become a hash on each iteration
so that the inner loop works without any problem?

There are two ways to do this: the first is to iterate over a list of
hashrefs:

for my $foo (\(%aries %taurus %gemini %leo)) {
for my $var (keys %$foo) {
print "$var => " . $foo->{$var} ."\n";
}
}

, the second, and better, way is to restructure your data to recognize
that these four hashes are all the same:

my %ips = (
aries => {
beta => "192.168.2.10",
gama => "192.168.2.11",
....
},
taurus => {
....
},
....
);

and then use either

for my $foo (keys %ips) {

or, if the order was important,

for my $foo (qw/aries taurus gemini leo/) {
for my $var (keys %{$ip{$foo}}) {
print "$var => $ips{$foo}{$var}\n";
}
}

Ben
 
G

gnari

Ravi Parimi said:
Hi ,

I have 4 hashes %aries, %taurus, %gemini, %leo, and each hash has
key=>value pairs like:

$aries{"beta"} = "192.168.2.10"
$aries{"gamma"} = "192.168.2.11"
and so on.

I would like to be able to print the contents of each hash without
explicity looping over the name of each hash.. I did something like:

foreach $foo qw /aries taurus gemini leo/ {
foreach $var (keys %foo) {
print "$var => $foo{$var}\n";
}
}

many ways, all involving references
one might be:

foreach $foo (\%aries,\%taurus,\%gemini,\%leo) {
foreach $var (keys %$foo) {
print "$var => $foo->{$var}\n";
}
}

but maybe the real answer is that you should consider changing
your datastructures.

you should read up on the perldocs before you try to go any further.
you will find it time well spent.

gnari
 
B

Brian McCauley

gnari said:
foreach $foo (\%aries,\%taurus,\%gemini,\%leo) {
foreach $var (keys %$foo) {

You should get into the habit of always declaring all variables in the
smallest applicable lexical scope unless there is a reason to do
otherwise.

Do this now - do not wait your for failure to do so to cause you pain.

In the case of the interator in a for(each) this means in the
for(each) statement itself.

for my $foo (\%aries,\%taurus,\%gemini,\%leo) {
for my $var (keys %$foo) {

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 
C

ctcgag

Ravi Parimi said:
Hi ,

I have 4 hashes %aries, %taurus, %gemini, %leo, and each hash has
key=>value pairs like:

$aries{"beta"} = "192.168.2.10"
$aries{"gamma"} = "192.168.2.11"
and so on.

I would like to be able to print the contents of each hash without
explicity looping over the name of each hash.. I did something like:

foreach $foo qw /aries taurus gemini leo/ {
foreach $var (keys %foo) {
print "$var => $foo{$var}\n";
}
}

I know it doesnt make sense to do it this way, but is there a way such
that $foo in the first loop above can become a hash on each iteration
so that the inner loop works without any problem?

Since you know it doesn't make any sense to do it this way, why
do you still want to do it this way? If the actual inner loop is
so monstrously hideous that you refuse to alter it to use hashrefs instead
of hashes, then you could do:

foreach my $ddd (\%aries,\%taurus,\%gemini,\%leo) {
my %foo=%$ddd;
### Monstrosity doing unholy things with %foo goes here.
%$ddd=%foo;
};

I'm ashamed to admit that I've used this shameful hack a few times to make
emergency alterations to god-aweful code that we didn't have time to
re-write.

Xho
 
B

Ben Morrow

Since you know it doesn't make any sense to do it this way, why
do you still want to do it this way? If the actual inner loop is
so monstrously hideous that you refuse to alter it to use hashrefs instead
of hashes, then you could do:

foreach my $ddd (\%aries,\%taurus,\%gemini,\%leo) {
my %foo=%$ddd;
### Monstrosity doing unholy things with %foo goes here.
%$ddd=%foo;
};

You don't need the final semi; also, the %$ddd=%foo should be in a
continue block. Alternatively, for real nastiness:

foreach my $ddd \(%aries, %taurus, %gemini, %leo) {
local *foo = $ddd;
### Monstrously unholy things with %foo here.
}

Note to OP[1]: I *would* *not* recommend this.

Ben

[1] and Uri ;)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,142
Latest member
DewittMill
Top