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

i am developing a web management system and am working with a hash of hashes of lists as so:
$hashoffiles->{$streamID}->{$filename} = (modsize, group, user etc...)
I am sure that i am constructing them correctly but when i try to loop though the second key i get the following error. For some reason it does not see $streamID as a hash but as a single variable
Can't use string ("1") as a HASH ref while "strict refs" in use at E:\ +Inetpub\cgi-bin\wms.pl line 176.
My construction code is
foreach my $dir (@dirList) { if(! -d $dir) { push @failDir, ($dir); next; } find { wanted => sub { #the @fileInfo array is created using the stat function but is irr +elevant for perlmonks my @fileInfo = ($mode, $user, $group, $size, $mtime, $type, $filen +ame, $filepath); #$hashOfStreams has two keys: 1 and 8 #Create a hash of files from source dir for each stream foreach my $key (keys %$hashOfStreams) { #ie $hashOfFiles->{'1'}->{'E:/mame.txt} = [ '$mode', '$user', +'$group'.. ]; #ie $hashOfFiles->{'8'}->{'E:/mame.txt} = [ '$mode', '$user', +'$group'.. ]; $hashOfFiles->{$key}->{$File::Find::name} = [ @fileInfo ]; #the following Debug code prints all vars correctly print "$key $File::Find::name $mode, $user, $group, $size, $mt +ime, $type, $filename, $filepath<br>"; } }, follow => 0}, "$dir"; }
my looping code is as follows
foreach $key (sort keys %$hashOfFiles) { #FAILS HERE - ERROR SAYS THAT $key is not a hash but a string foreach my $file (sort keys %$key) { my ($mode2, $user2, $group2, $size2, $mtime2, $filename, $f +ilepath) = @{$hashOfFiles->{$key}->{$file}}; print "$file - $filename, $filepath, $mode2 $user2, $group2, $ +size2, $mtime2<br>"; } }
Can anyone who has dealt with complex vars see the problem? I have been looking for hours but cannot see it? Is it possible to create vars as complex as this?

Costas

Replies are listed 'Best First'.
Re: hash of hashes of lists!!!
by Juerd (Abbot) on Apr 05, 2002 at 14:26 UTC

    i am developing a web management system and am working with a hash of hashes of lists as so: $hashoffiles->{$streamID}->{$filename} = (modsize, group, user etc...) I am sure that i am constructing them correctly but when i try to loop though the second key i get the following error.

    Be less sure, or update your example code.

    $foo->{bar}->{baz} is a scalar, and when you assign to a scalar, there is scalar context. In scalar context, a list evaluates to its last element.
    You can't have a hash of hashes of lists, but you can have a hash of hashes of arrays. A list is always temporary, for storing, you need an array.

    However, in your code you use square brackets, and do it the right way. I don't see the problem, and it would be a LOT easier for us if you added a note so we know which line is line 176. In the meanwhile, try dumping your data structure using Data::Dumper to see if it contains what you want it to.

    U28geW91IGNhbiBhbGwgcm90MTMgY
    W5kIHBhY2soKS4gQnV0IGRvIHlvdS
    ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
    geW91IHNlZSBpdD8gIC0tIEp1ZXJk
    

Re: hash of hashes of lists!!!
by strat (Canon) on Apr 05, 2002 at 14:54 UTC
    Better try something like:
    foreach my $key (sort keys %$hashOfFiles) { foreach my $file (sort keys %{ $hashOfFiles->{$key} }) # foreach my $file (sort keys %$key) { my ($mode2, $user2, $group2, $size2, $mtime2, $filename, $filepath +) = @{ $hashOfFiles->{$key}->{$file} }; #...
    Btw: very often it is a good idea checking more complicated datastructures with Data::Dump or Data::Dumper (especially if you are not sure if you are constructing them in the right way).

    Best regards,
    perl -le "s==*F=e=>y~\*martinF~stronat~=>s~[^\w]~~g=>chop,print"

Don't use the key, use the hash ref...
by RMGir (Prior) on Apr 05, 2002 at 14:30 UTC
    You're using the key instead of the hash entry as your reference in your keys statement...
    foreach $key (sort keys %$hashOfFiles) { #foreach my $file (sort keys %$key) foreach my $file (sort keys %{$hashOfFiles->{$key}})

    --
    Mike

    Edit: Was using %() instead of %{} to wrap the hash reference. :(

Re: hash of hashes of lists!!!
by costas (Scribe) on Apr 05, 2002 at 14:34 UTC
    line 176 is
    foreach $key (sort keys %$hashOfFiles) { #LINE 176 foreach my $file (sort keys %$key) { my ($mode2, $user2, $group2, $size2, $mtime2, $filename, $f +ilepath) = @{$hashOfFiles->{$key}->{$file}}; print "$file - $filename, $filepath, $mode2 $user2, $group2, $ +size2, $mtime2<br>"; } }
    I am using arrays and not lists. Sorry for not making it clear. I am updating my code from a previous version so i am sure that the array works fine.

    You said: $foo->{bar}->{baz}
    The failure is recognising 'bar' as a scalar rather than a hash and is (i think) nothing to do with 'baz' being a scalar or array.

      The failure is recognising 'bar' as a scalar rather than a hash and is (i think) nothing to do with 'baz' being a scalar or array.

      bar is an unquoted string, baz is an unquoted string.
      $foo->{bar} is a scalar, holding a hash reference.
      %{ $foo->{bar} } is the hash to which $foo->{bar} is refering.
      $foo->{bar}->{baz} is a scalar.

      U28geW91IGNhbiBhbGwgcm90MTMgY
      W5kIHBhY2soKS4gQnV0IGRvIHlvdS
      ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
      geW91IHNlZSBpdD8gIC0tIEp1ZXJk
      

Re: hash of hashes of lists!!!
by tachyon (Chancellor) on Apr 06, 2002 at 01:44 UTC
    use Data::Dumper; # assemble you data structure $structure = { 1 => { 1 => [1,2,3], 2 => [2,4,6] }, 2 => { 1 => [2,4,6], 2 => [4,8,12] } }; print Dumper($structure); my ( $one, $two, $three) = @{$structure->{'1'}->{'1'}}; print "$one, $two, $three\n";

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print