Access Data Dumper嵌套Perl Hash

时间:2015-02-02 13:30:09

标签: json perl hash hashref data-dumper

我有一个使用Data :: Dumper打印的Perl哈希引用$artifact

print Dumper ($artifact);的输出会返回以下内容。

$VAR1 = bless( {
             '_content' => '{
  "results" : [ {
"uri" : "http://localhost:port/myfile.tar"
   } ]
}',);

但是,我无法专门访问URI的值,即我想检查uri是否有值。

谢谢!

编辑:只是一些背景。我正在使用Artifactory :: Client perl模块中的'artifact_search'方法

3 个答案:

答案 0 :(得分:6)

要从哈希引用中提取信息,首先需要取消引用。你可以:

print ${$artifact}{uri},"\n"; 

在这种特定情况下,您可以省略大括号,只需执行:

print $$artifact{uri},"\n"; 

但要注意,这可能是模棱两可的,因此符号的风格并不总是适用于解除引用。

或更新的,可能更清晰的符号(例如像面向对象)

print $artifact->{uri},"\n";

然而,这里有一个很大的警钟 - bless - 这意味着你可能正在操纵一个物体。在一个对象内戳是非常脏的。你不应该这样做。 通常该对象将包含一个访问器方法,为您提供所需的信息。按照惯例,_前缀表示private,例如'不要乱用'。 (不管怎样你都应该这样做)

如评论中所述 - 这是嵌入在对象中的JSON文本字符串。因此,如果您真的开始这样做 - 您可以解析JSON,将其转换为perl数据结构,然后使用它。

但更有可能的是 - 您正在操作的对象内置了一些存取方法,您应该使用它们。

所以给出上面的例子:

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use JSON;

my $hashref = {
    _content => '{
      "results" : [ {
"uri" : "http://localhost:port/myfile.tar"
   } ]
}'
};

print Dumper \$hashref;

my $json    = JSON->new();
my $json_ob = $json->decode( $hashref->{_content} );
print Dumper \$json_ob;
print $json_ob ->{results}->[0]->{uri};

然而,如评论中所述,您正在使用: Artifactory::Client非常合理地使用LWP

  

此模块中提供的每个公共方法都返回一个HTTP :: Response对象。

参考HTTP::Response文档提供此示例:

if ($artifact->is_success) {
    print $artifact->decoded_content;
}
else {
    print STDERR $artifact->status_line, "\n";
}

答案 1 :(得分:2)

就Perl而言,您的$artifact变量是具有单个键/值对的哈希引用。 URI嵌入在值中,该值似乎是JSON。您需要提取值,解析它,然后获取URI。

JSON是YAML的有效子集,因此您可以使用YAML模块对其进行解析。

use YAML::XS;
my $content = $artifact->{_content};
my $yaml    = Load($content);
print $yaml->{results}[0]{uri}; # http://localhost:port/myfile.tar

也就是说,方法/属性名称的前导下划线通常意味着它们对类是“私有”的,不应该在外部使用。偷看API(我们无法知道数据来自何处以及哪个类$artifact被祝福)是脆弱的。

答案 2 :(得分:0)

这不是你从Dumper得到的确切输出,是吗?如果Dumper输出包含对bless的调用,那么它还应该包含引用已被祝福的类的名称。

天真的做法是:

print $artifact->{_content}{results}[0]{uri};

但是鉴于你似乎有一个对象(一个有福的哈希引用),那么几乎可以肯定的是,类上的方法可以访问对象的属性。你应该使用它们而不是在对象的内部挖掘。

更新:是的,我错过了整个_content密钥是一个JSON字符串。抱歉: - /