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


in reply to Mulitple values for a key in a hash

perldsc tutorial will help you understand Perl data structures, especially HoH (HASHES OF HASHES).


  • Comment on Re: Mulitple values for a key in a hash

Replies are listed 'Best First'.
Re^2: Mulitple values for a key in a hash
by wishartz (Beadle) on Nov 29, 2007 at 16:29 UTC
    I read about the hash of hashes and tried the following. Although, the check doesn't seem to work, it prints error when the condition should be false. Does anybody know where I'm going wrong?
    $filesystem = $ARGV[0]; #store the file system you would like to run D +U command on if ( $ARGV[0] eq "" ) { die "usage: $0 filename\n"; } $host=`hostname`; my %filesystems = ( hosta => { desc => 'x', filesystemA => [ q +q|/the/first/filesystem|], filesystemB => [ qq|/the/second/fielsyste +m| ] }, hostb => { desc => 'r', filesystemA => [ q +q|/the/first/filesystem | ], filesystemB => [qq|no filesystemB for 2n +d host |]} ); $choice = $filesystems{$host}; if ( not $filesystems{filesystemA}{$filesystem} ) { print "error\n"; }
      wishartz:

      I think this is a bit more like what tcf03 was suggesting:

      #!/usr/bin/perl -w #added use strict; #added use Data::Dumper #added my $host = $ARGV[0]; #update was 'hosta'; my $fsys = $ARGV[1]; #update was qq|/the/second/filesystem|; my %filesystems = ( hosta => { #update desc => 'x', filesystems => { #update qq|/the/first/filesystem| => 0, qq|/the/second/filesystem| => 0 } #update }, #update hostb => { #update desc => 'r', filesystems => { #update qq|/the/first/filesystem| => 0, qq|no filesystemB for 2nd host | => 0 } #update } #update ); print Dumper(\%filesystems); #added if ( ! exists $filesystems{$host}{filesystems}{$fsys} ) { print "error\n"; } else { print "Found filesystem $fsys on host $host\n" . $filesystems{$host}{descr} . "\n"; }
      Note: Untested!

      ...roboticus Update: You'll notice that this node has been edited heavily. I've added some lines (suitably marked), included Data::Dumper (which is how I found my goofs). The error was that I used parenthesis () instead of curlies {} in my hash declarations.

        At the momment I am using the following: But it is still reporting an error, even though, I am running it on the correct host and the file system is on the host. Is the check correct? Am I defreferencing it properly?
        $host=`hostname`; $filesystem = ARGV[0]; my %filesystems = ( hosta => (desc => 'x', filesystems => (qq|/dat +a/file/a| =>0, qq|/data/file/b| =>0)), tx05 => (desc => 'r',filesystems => (qq|/data/ +file/c| =>0, qq|no filesystemB for 2nd host | => 0))); if ( ! exists $filesystems{$host}{filesystems}{$filesystem} ) { print "error\n";} else {print "Found filesystem $filesystem on host $host\n". $filesyste +ms{$host}{descr}."\n";}
        Roboticus your program worked. Thanks so much roboticus and everybody else who helped.
      In case that you need hash key existance (and not only) check use exists.
      my %filesystems = ( hosta => { desc => 'x', filesystemA => qq|/the/first/filesystem|, +filesystemB => qq|/the/second/fielsystem| }, hostb => { desc => 'r', filesystemA => qq|/the/first/filesystem|, f +ilesystemB => qq|no filesystemB for 2nd host|} ); print "filesystemA exists\n" if exists $filesystems{'hosta'}->{'filesystemA'}; print "no_such_fs does not exist\n" if not exists $filesystems{'hosta'}->{'no_such_fs'};


        Dear Monks, I've tried making the hashes in the way that has been suggested to me, but the check does not work. It will always print out the message 'error', regardless of which host I am on and which file system I have chosen. So, the check always comes up as true, even when it should be false. I think the if condition just gives a reference and not the value. Can anybody help me with this? Ive hit a dead end, with it. Would I be better of making a nested foreach loop, with the outer hash key and the inner hash key and making a check that way?
        I'm sorry if this is a duplicate post, but I think I put my reply in the wrong place. At the momment I am using the following: But it is still reporting an error, even though, I am running it on the correct host and the file system is on the host. Is the check correct? Am I defreferencing it properly? The first if condition should have been false, but instead it is coming out as true and printing out error.
        $host=`hostname`; $filesystem = ARGV[0]; my %filesystems = ( hosta => (desc => 'x', filesystems => (qq|/dat +a/file/a| =>0, qq|/data/file/b| =>0)), tx05 => (desc => 'r',filesystems => (qq|/data/ +file/c| =>0, qq|no filesystemB for 2nd host | => 0))); if ( ! exists $filesystems{$host}{filesystems}{$filesystem} ) { print "error\n";} else {print "Found filesystem $filesystem on host $host\n". $filesyste +ms{$host}{descr}."\n";}