de**********@yahoo.com (Christopher) wrote in message news:<e8**************************@posting.google. com>...
I have a hash that is several levels deep.
ie:
'vars' => {
'$filers' => '10.10.10.10/32',
'$networksa' => '10.10.10.10/32',
'$networksb' => '10.50.0.0/16',
'$wintel_boxes' => '10.10.10.10/32',
},
'match' => {
'Rule' => {
'Doug' => {
'RuleSub' => {
'OUTBREAK' => {
Basically a structure similar in nature to that, basically it could go
as deep as 8 keys deep with values potentially with each key, but
usually a value as some level.
I need to iterate over this and print it out in it's structure, but
with some formatting. DataDumper does a fine job of doing it in it's
way, but I cannot customize the pretty output, plus I need to utilize
the data in other ways.
So I figure I can load the "top level" keys (say there are 3 of them),
and then recurse over each subsequent key and gather and print as I
go.
Here is what I tried:
use Config::General;
my $match_file = qq(match.conf);
my $match_conf = new Config::General(
-file => $match_file,
-AutoTrue => 1);
my %match_config = $match_conf->getall;
$depth = 0;
You forgot to declare $depth. "use strict" would have told you about
this.
foreach $key (keys %match_config) {
print "\t"x$depth;
You forgot to declare $key. "use strict" would have told you about
this.
print "\n$key\n";
$depth++;
&recurse_hash($match_config{$key},$depth);
Why is that & in there? Do you know what it does? Do you really want
to do that?
Assuming $depth is supposed to indicate the depth within the
structure, it would be more straight-forward to do
recurse_hash($match_config{$key},1);
Anyhow it's not clear why you treat the top level specially at all.
recurse_hash(\%match_config,0);
}
sub recurse_hash {
$match = shift;
You forgot to declare $match. "use strict" would have told you about
this. By choosing not to "use strict" you instruct Perl to assume any
variable you didn't declare is a package variable and thus a global
variable with respect to the subroutine. Using global variables in
recursive subroutines is bad.
$depth = shift;
Ouch - you forgot to redeclare $depth within the subroutine. "use
strict" would not have helped you directly. But the mind-set that
goes with "use strict" that says "always declare all variables
lexically scoped in the smallest lexical scope" would have made this
error much less likely.
print "\t"x$depth;
You probably wanted that on each line - i.e inside the loop.
foreach $key2 (keys %{$match}) {
You forgot to declare $key2. "use strict" would have told you about
this.
print "$key2 => $match->{$key2}\n";
($match,$depth) = &recurse_hash($match->{$key2},$depth);
You are forgetting to check that $match->{$key2} really is a hash ref
either before you call &recurse_hash or within that inner subroutine.
"use strict" would have told you about this because you'd have got an
error when you tried to use something that wasn't a hash ref as a has
ref. Without "use strict" Perl will attempt to convert the string
into a reference by performing a symbol table lookup - this is bad.
Once again assuming $depth is supposed to indicate the depth within
the structure, you should be calling recurse_hash with $depth+1.
}
return ($match,$depth);
}
I do not understand why &recurse_hash needs to return this.
sub recurse_hash {
my $match = shift;
my $depth = shift;
return unless ref $match eq 'HASH';
foreach my $key2 (keys %{$match}) {
print "\t"x$depth, "$key2 => $match->{$key2}\n";
recurse_hash($match->{$key2},$depth+1);
}
}
I have racked my brain on this, and scoured
the groups for anykind of similar problem.
The consequences of being careles about your variable scoping and
choosing not to "use strict" are often discussed (oftem many times per
day) in the Perl newsgroups that exist. But, of course, you could not
be expected to realise that those are all "similar problems".
I would have thought recursive traversal of Perl structures is
dicussed frequently in the Perl newsgroups that exist. Usually at
least once a month. But actually, having Googled "recursive reference
group:comp.lang.perl.*" it does seem much less common than I'd expect.
Indeed the last thread I could find asking substancially the same
question as you are asking was the sixth hit I got and was way back in
August/September.
That said trawling though six hits isn't all that ownerous. When you
"scoured
the groups for anykind of similar problem" what keywords did you try?
This newsgroup does not (see FAQ). Please do not start threads here.