in reply to unblessed reference problem

Step through each key you pass in, and recurse into each hash with that key, like this (but not so ad-hoc and ugly):

#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $arr = { a => { b => 'c', d => { e => { x => 'y', k => [ 'A'...'Z'], } } , }, f => { g => 'h', i => 'm' } }; sub arr_parse { my $data = shift; my @params = @_; my $newdata = $data; foreach my $parm (@params) { if (ref $newdata eq 'ARRAY') { $newdata = $newdata->[$parm] } elsif (ref $newdata eq 'HASH') { $newdata = $newdata->{$parm} } else { last } } return $newdata } my $retval = arr_parse( $arr, qw{a d e x} ); print Dumper( $retval ) . "\n"; my $retval2 = arr_parse( $arr, qw{a d e k 15} ); print Dumper( $retval2 ) . "\n";
EDIT: Updated to deal with hashes and arrays.

Replies are listed 'Best First'.
Re^2: unblessed reference problem
by gdolph (Novice) on Mar 26, 2010 at 11:51 UTC

    Thanks james2vegas, that is definitely a very good solution to this specific problem. What I really want to know is how to get perl to do what I originally posted. I'm well aware some of the more esoteric solutions might be dangerous, but I still want to know how it works to further my knowledge.

      but I still want to know how it works

      If you're referring to the eval thing, that would be:

      #!/usr/bin/perl -l use strict; use warnings; my $hash = { domain => { foo => { bar => "baz" } } }; my $domain = "domain"; my $var1 = "foo"; my $var2 = "bar"; my $test = '{$var1}{$var2}'; my $value = eval '$hash->{$domain}'.$test; print $value; # "baz"

      That said, better stay away from eval unless you know what you're doing, because

      • it's potentially dangerous when you overlook something (e.g. when the value of $test might originate from somewhere not under your full control)
      • code using it is unnecessarily hard to read and maintain
      • it's unnecessarily slow

        That's excellent stuff, thanks almut! Just what I needed to know.

      *sigh* To make $hash->{$domain}$test; into $hash->{$domain}{$var1}{$var2} you have to write $foo such that print $foo prints $hash->{$domain}{$var1}{$var2}, then you can eval $foo to execute.