-1

I am working on a requirement in which keys of hash are hash. I came across the cpan modue Tie::RefHash which can do the job, but somehow it is not working for nested hashes even though I am using Tie::RefHash::Nestable.

my %hash_arg = ();
tie %hash_arg, 'Tie::RefHash::Nestable';
my $hash = { 'mnp' => 1 };
%hash_arg = (
    'pqr' => {
        'a;'  => 1,
        'i'   => 1,
        'mn'  => 1,
        'c'   => 1,
        $hash => 1
    }
);

Hash %hash_arg has a key pqr whose value is a reference to a hash, which has a further hash as a key. When I loop over keys of pqr and try to use the ref function to figure out the hash, it doesn't work.

Sharad
  • 1,867
  • 14
  • 33
  • 4
    You must *always* `use strict` and `use warnings 'all'` at the top of *every* Perl program. Try it with your code aboev, it may give you some clues about what you have done wrong – Borodin Oct 28 '15 at 13:30
  • 2
    This sound an awful lot like an [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) - why are you trying to use hashes as keys for hashes? – Sobrique Oct 28 '15 at 13:36
  • I have both strict and warning enabled. – Sharad Oct 28 '15 at 13:38
  • I have enabled both strict and warning. No warning or error is found on running the code. The thing I am receiving the data which is in the form I described. The data has been Tied using Tie::RefHash. I have to make sense out of that. That's where I am facing the problem. I could not find a proper reference or solution anywhere. – Sharad Oct 28 '15 at 13:42
  • Really? Because when I try `my %hash_arg = {};` in `strict` and `warnings` I get: "Reference found where even-sized list expected". – Sobrique Oct 28 '15 at 13:47
  • 4
    *"I have enabled both strict and warning. No warning or error is found on running the code."* That's funny, because when I run your code under `strict` and `warnings` I get ***Reference found where even-sized list expected*** It's much appreciated if you don't lie to us on Stack Overflow – Borodin Oct 28 '15 at 13:54
  • I think I did a typo in writing the question. It should be my %hash_arg = (); Sorry about that. I am working with both perl and python interchangebly so got the syntax mixed – Sharad Oct 28 '15 at 16:44

1 Answers1

1

The reason your code isn't working is that Tie::RefHash works, obviously, through Perl's tie mechanism. That means it does its magic through tie's operations like STORE, FETCH, FIRSTKEY, NEXTKEY etc.

Your initialisation statement where you set up %hash_arg bypasses all of that, by making the compiler construct a hash which is assigned directly instead of through the tie mechanism

If you rewrite your code so that the key that is a hash reference is applied at run time then it all works fine

Take a look at this rewrite of your program. You can see from the dump that the inner hash has all four string keys, a string key HASH(0xd4c2f8) that the compiler assigned, and a proper hash reference key that appears as HASH

use strict;
use warnings 'all';
use v5.10;

use Tie::RefHash;
use Data::Dump;

tie my %hash_arg, 'Tie::RefHash::Nestable';

my $hash = { 'mnp' => 1 };

%hash_arg = (
    pqr => {
        'a;'  => 1,
        i     => 1,
        mn    => 1,
        c     => 1,
        $hash => 1,
    },
);

$hash_arg{pqr}{$hash} = 1;

for my $key ( keys %{ $hash_arg{pqr} } ) {
    dd (ref $key or $key);
}

output

"HASH"
"mn"
"c"
"i"
"HASH(0xd4c2f8)"
"a;"
Borodin
  • 126,100
  • 9
  • 70
  • 144