http://www.perlmonks.org?node_id=832862

jedikaiti has asked for the wisdom of the Perl Monks concerning the following question:

I have a hash, much like the one below:

%cmdData = ( 'command_1' => { 'subfields' => [], 'description' => 'descriptive text', 'safety' => 'SAFE' }, 'command_2' => { 'subfields' => [ { '_size' => 32, 'state_conversions' => [], 'subfield_name' => 'sub_1', '_fsw_type' => 'UINT32', }, { '_size' => 32, 'state_conversions' => [], 'subfield_name' => 'sub_2', '_fsw_type' => 'UINT32', }, ], 'description' => 'descriptive text', 'safety' => 'SAFE', } )

What I want to do is to loop through each command (key) in the hash, and do X if it has one or more subfields, and Y if it has 0 subfields. So I have a foreach loop in my code (below), with an if/else statement.

Problem is, I can't get the if/else conditions right. I have tried it as below, and I have tried if (not defined $cmdData->{$cmd}{subfields}). In both cases, it prints all the command names, followed by "defined".

#!/usr/bin/perl -w use strict; use warnings; use Storable; my %info; my $cmdData = retrieve('file.pm') foreach my $cmd ( sort { $cmdData->{$a}{pkt_target} cmp $cmdData->{$b} +{pkt_target} || $a cmp $b } keys %{$cmdData}) { print "$cmd "; if ($cmdData->{$cmd}{subfields} eq "") { print "undef\n"; } else { print "defined\n"; } };

Yes, I can change the hash I'm working with - sort of. I have a preprocessing script that is compiling a whole mess of hashes of the same format into one big one in a file (so it's easier to iterate through later). I can change that script to output something nicer, but I still need to know how to tell if there are subfields or not (this is how they appear in the original hashes I'm pulling from) so I can fix them.

Thanks a million, Monks!

Kaiti
Swiss Army Nerd

Replies are listed 'Best First'.
Re: Iterating through a HoHoH ... does a particular sub-hash exist?
by ikegami (Patriarch) on Apr 05, 2010 at 17:46 UTC

    $cmdData->{command_1}{subfields} is defined. It's an array reference.
    $cmdData->{command_2}{subfields} is defined. It's an array reference.

    Sounds like you want to check the number of elements in the referenced array. That would be

    @{ $cmdData->{$cmd}{subfields} }
    in scalar context.
Re: Iterating through a HoHoH ... does a particular sub-hash exist?
by CountZero (Bishop) on Apr 05, 2010 at 19:05 UTC
    Are you using the strictures, jedikaiti?

    If you did, you would have seen that

    $cmdData->{$cmd}{subfields}
    gives you an error, unless you have elsewhere declared $cmdData.

    $cmdData->... contains a scalar reference and has nothing to do with your hash %cmdData. You probably meant something like $cmdData{'command_2'}->{subfields}.

    Update: Forget what I wrote above. I somehow totally missed the code in your node. Thanks almut for pointing that out to me.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      I guess the retrieve in my $cmdData = retrieve('file.pm') would return a reference to the hash in question, so things should be fine.