SPUG: Dereferencing hash ref

Evgeny Roubinchtein evgenyr at cs.washington.edu
Tue Aug 6 18:02:38 CDT 2002


>>>>> "EB" == Brose, Eric <eric.brose at attws.com> writes:

    EB> Hello,
    EB> I'm using the XML::Simple module and need to recurse over my results.

    EB> use XML::Simple;
    EB> use Data::Dumper;
 
    EB> my $ref = XMLin('C:\Perl\HBSource.xml');

    EB> print Dumper($ref);

    EB> foreach $setting (sort keys (%$ref)){
    EB>      #print "$setting\n";  This works!
    EB> 	foreach $detail (sort keys %{$ref{$setting}} ){
    EB> 		print "$ref{$setting}->{$detail}\n";
    EB> 	}
    EB> }
    EB> ;

    EB> I'm trying to figure out how to review all of the info in the
    EB> hash ref.  Can someone give me some clues how i can change my
    EB> foreach nested loops to get our what I want.

Personally, I would write the inner foreach as:
        foreach $detail (sort keys %{$ref->{$setting}) {
                print $ref->{$setting}->{$detail}, "\n";
        }

Do "perldoc perlref" for the full story.  If something in the perlref
documentation doesn't make sense, or you need more examples, feel free
to ask again.

    EB> I need to be able to recurse through my data structure(the
    EB> hash ref) to extract this info. Any ideas?

I'm probably sounding like Mr. Obvious, but, if you want to _recurse_,
it seems that recursion would be more appropriate than iteration, no?

sub recurse_thang ($);

# this code is mostly "for illustration", rather than "for production use"
sub recurse_thang ($) {
        my $thang = shift;

        if (not ref $thang) { # the base case: a plain scalar
             print $thang, ", ";
             return;
        }


        if ( ref($thang) eq 'HASH') {
             print "{ ";
                  foreach my $key (sort keys %$thang) {
                        print $key, " =>  ";
                        recurse_thang($thang->{$key});
                }
             print "}\n";
        }
        elsif ( ref($thang) eq 'ARRAY') {
                print "[ ";
                foreach my $item (@$thang) {
                        recurse_thang($item);
                }
                print "]\n";
        }
        elsif ( ref($thang) eq 'SCALAR' ) {
             print $$thang, ", ";
        }
        # ... more cases here ...
}

my $ref = { foo => [1, 2, 3],
            bar => [ {baz => 5}, 4, 8],
      };

recurse_thang($ref);


Hope this helps.

-- 
Evgeny

Faced with the choice between changing one's mind, and proving that there is
no need to do so - almost everyone gets busy on the proof.
  -- John Kenneth Galbraith


 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     POST TO: spug-list at pm.org       PROBLEMS: owner-spug-list at pm.org
      Subscriptions; Email to majordomo at pm.org:  ACTION  LIST  EMAIL
  Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
 For daily traffic, use spug-list for LIST ;  for weekly, spug-list-digest
     Seattle Perl Users Group (SPUG) Home Page: http://seattleperl.org




More information about the spug-list mailing list