-1

Alright I have a function which generates a hash tree that dumper prints out to look like this:

$VAR1 = {
  'shaders' => {
    'stock_gui.vert' => '',
    'stock_font.vert' => '',
    'stock_gui.frag' => '',
    'stock_font.frag' => ''
  },
  'textures' => {},
  'fonts' => {
    'DroidSansMono.ttf' => '',
    'small' => {
      'DroidSansMono.ttf' => ''
    }
  }
};

Now I am trying to dfs iterate for example the fonts sub tree:

push (@stack, \%{$myHash->{'fonts'}});

Then in a loop:

my $tmpHash = pop(@stack);

Then a dumper of $tmpHash shows:

$VAR1 = {
  'DroidSansMono.ttf' => '',
  'small' => {
    'DroidSansMono.ttf' => ''
  }
};

The problem is trying access the children of the hash reference. I can count the keys and see the children. The dumper output looks okay. However trying to do something like:

foreach my $childKey ( keys $tmpHash ){
   my $subChildrenCount = scalar keys(%{$tmpHash->{$childKey}});
}

Yields the error:

Can't use string ("") as a HASH ref while "strict refs" in use

I think this is because $tmpHash is a hash reference. I likely just need to dereference it somewhere. I've tried many things and all yields further issues. Any help appreciated.

If I try:

 %{$tmpHash->{'small'}}

Then it works fine.

UPDATE:

  • If the string contains a '.' then this error occurs. Hard coding 'small' works. Hard coding 'stock_gui.vert' fails unless I escape the '.'. However the keys do not match if I escape the dot...
Halsafar
  • 2,540
  • 4
  • 29
  • 52
  • You should take a look at [perlref](http://perldoc.perl.org/perlref.html). Looks like you're confused about `\\` and `$hash_ref`. – chrsblck Apr 19 '13 at 22:05
  • By the way, `\%{pop(@stack)}` is a weird way of doing `pop(@stack)`. – ikegami Apr 19 '13 at 22:06
  • My perl is rusty, I won't argue there. Reading up on it. Pop was weird... pop(@stack) by itself works fine. – Halsafar Apr 19 '13 at 22:10
  • You don't need to do constantd referencing and dereferencing via "\%{xxx}" - which is the same as simply "xxx" for you. – DVK Apr 19 '13 at 22:15
  • `%$ref` dereferences the hash, then `\ ` creates a reference to it. it's like doing `$n-1+1`. – ikegami Apr 20 '13 at 02:29

1 Answers1

1

As you can see by running it yourself,

use strict;
use warnings;

my $tmpHash = {
  'DroidSansMono.ttf' => '',
  'small' => {
    'DroidSansMono.ttf' => ''
  }
};

my $subChildrenCount = scalar keys(%{$tmpHash->{'small'}});

the code you say gives that error does not actually give that error. I suspect you are actually doing

my $subChildrenCount = scalar keys(%{$tmpHash->{'DroidSansMono.ttf'}});

Your hash format doesn't make much sense. It mixes field names and actual data as keys.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • If I use my existing code but hardcode the keys then it works. If I do a foreach key loop and try and reference the key as a var then it gives that error. Yes it is a weird hash format, for an odd job. Hashes with children are directory, hashes with no children are files. No more information is required. – Halsafar Apr 19 '13 at 22:08
  • See the update. It seems to be all about the '.' in the key string. Unfortunately if I escape the '.' with some regex then that error disappears and everything iterates fine except 'Foo\.ext' won't match the key 'Foo.ext'. – Halsafar Apr 19 '13 at 22:22
  • No, there' no problem with keys with periods itself. Stop blaming Perl for bugs in your code. – ikegami Apr 20 '13 at 02:28
  • A common response from you... If $myKey contains the string "foo.bar" it gives the error about not being able to use an empty string as a hash ref. If $myKey contains "foo_bar" it works perfect. If I escape the dot with a sed it works but keys do not match anymore. I have "$myKey" wrapped in double quotes. – Halsafar Apr 22 '13 at 19:10
  • Nonsense. You get that error when the $x is the empty string in $x->{$mykey}, not when $x or $mykey contains `foo.bar`. – ikegami Apr 22 '13 at 19:12
  • Using dumper when the value of $myKey is: $VAR1 = 'stock_gui.vert'; The error I posted above occurs. When dumper shows it as $VAR1 = 'small'; The code works fine. If I change the hash to be 'stock_gui_vert' it works just fine. – Halsafar Apr 22 '13 at 19:18
  • What's this got to do with your question or my answer?! – ikegami Apr 22 '13 at 20:19
  • Again, if you get "Can't use string ("") as a HASH ref", it's because you are doing `$x->{$y}` and `$x` contains an empty string. – ikegami Apr 22 '13 at 20:33