2

首先,关于我所说的各种 Perl 语言结构,请更正我在标题和正文中的语言!

我无法将变量传递给哈希引用。具体来说,我使用 JSON 模块来解码一些 JSON 数据,然后访问该数据的特定部分。

这是我的 JSON 数据示例:

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

现在这是我的 Perl 代码:

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 ));

有没有办法做到这一点?谢谢!

4

2 回答 2

3

虽然使用 eval 可以做到这一点,但这种方法存在问题。

我怀疑这是解决您潜在问题的更好答案:

use Data::Diver;
my @datapath = ( 0, 'data', 0, 0 );
print( Dumper( Data::Diver::Dive($decoded_json, @datapath) ));
于 2013-07-08T15:30:09.970 回答
2

这通常是不可能的,但有一些解决方法:

  1. 做一个字符串eval- :

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

    当然,eval以这种方式使用是不受欢迎的。

  2. 定义一个遍历数据结构的函数:

    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);
    

    当然,这会因重载对象而失败。

于 2013-07-08T15:30:56.203 回答