简体   繁体   中英

How do I pass a variable as a method to a Perl hash reference?

First of all, please correct my language in the title and body as regards what I'm calling the various Perl language constructs!

I'm having trouble passing a variable to a hash reference. Specifically, I'm using the JSON module to decode some JSON data and then access specific parts of that data.

Here is a sample of my JSON data:

[
 {
  label:"Blah",
  data:[
     [ 2112, 1 ]
  ]
 }
]

Now here is my Perl code:

use JSON;
use Data::Dumper;
my $json = "*JSON data above*";
my $decoded_json = decode_json($json);

# This works, prints out '2112':
print( Dumper( $decoded_json->[0]{'data'}[0][0] ));

# What I'd like to do:
$datapath = "[0]{'data'}[0][0]";
print( Dumper( $decoded_json->$datapath ));

Is there a way to do this? Thanks!

While it is possible to do that using eval, there are problems with that approach.

I suspect this is a better answer for your underlying problem:

use Data::Diver;
my @datapath = ( 0, 'data', 0, 0 );
print( Dumper( Data::Diver::Dive($decoded_json, @datapath) ));

This isn't generally possible, but there are workarounds:

  1. do a string- eval :

     my $val = do { local $@; my $val = eval "\\$decoded_json->$datapath"; die $@ if $@; $val; }; 

    Of course, using eval in this way is frowned upon.

  2. Define a function that walks a data structure:

     sub walk { my $data = shift; while (@_) { my $index = shift; if (ref $data eq 'HASH') { $data = $data->{$index}; } elsif (ref $data eq 'ARRAY') { $data = $data->[$index]; } else { die qq(Wanted to use index "$index", but "$data" is neither hash nor array); } } return $data; } my $val = walk($decoded_json, 0, 'data', 0, 0); 

    Of course, this would fail with overloaded objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM