简体   繁体   English

访问数据转储器嵌套 Perl 哈希

[英]Access Data Dumper nested Perl Hash

I have a Perl hash reference $artifact that I am printing using Data::Dumper.我有一个 Perl 哈希引用$artifact ,我正在使用 Data::Dumper 打印它。

The output of print Dumper ($artifact); print Dumper ($artifact);的输出print Dumper ($artifact); returns the following.返回以下内容。

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

However, I am having trouble trying to specifically access the value of URI, ie I want to check if uri has a value or not.但是,我在尝试专门访问 URI 的值时遇到了麻烦,即我想检查uri是否具有值。

Thanks!谢谢!

Edit: Just some context.编辑:只是一些背景。 I am using the 'artifact_search' method from the Artifactory::Client perl module我正在使用 Artifactory::Client perl 模块中的“artifact_search”方法

To extract information from a hash reference, first you need to dereference.要从散列引用中提取信息,首先需要取消引用。 You can either:您可以:

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

In this specific case, you can omit the braces and just do:在这种特定情况下,您可以省略大括号,只需执行以下操作:

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

But be aware that that can be ambiguous so the style of notation doesn't always work for dereferencing.但请注意,这可能是模棱两可的,因此符号样式并不总是适用于取消引用。

Or the newer, and probably clearer notation (eg like object oriented)或者更新的,可能更清晰的符号(例如面向对象)

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

However, there is a BIG alarm bell here - bless - this means you're manipulating an object, probably.然而,这里有一个很大的警钟—— bless ——这意味着你可能正在操纵一个对象。 Poking inside an object is VERY dirty.在物体内部戳是非常脏的。 You shouldn't ever do it.你永远不应该这样做。 Usually the object will contain an accessor method to give you the information you need.通常该对象将包含一个访问器方法来为您提供所需的信息。 By convention, an _ prefix denotes private eg 'don't mess with this'.按照惯例, _前缀表示private例如“不要弄乱这个”。 (Not that you should anyway) (无论如何你都不应该)

As noted in the comments - this is a JSON text string embedded within your object.如评论中所述 - 这是嵌入在您的对象中的 JSON 文本字符串。 So if you were really set on doing this - you can parse the JSON, turn it into a perl data structure, then use that.因此,如果您真的打算这样做 - 您可以解析 JSON,将其转换为 perl 数据结构,然后使用它。

But far more likely - the object you're manipulating has some accessor methods built in, and you should use them.但更有可能 - 您正在操作的对象内置了一些访问器方法,您应该使用它们。

So given your example above:因此,鉴于您上面的示例:

#!/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};

However as mentioned in comments, you're using: Artifactory::Client which quite sensibly uses LWP .但是,正如评论中提到的,您正在使用: Artifactory::Client非常明智地使用LWP

Every public method provided in this module returns a HTTP::Response object.此模块中提供的每个公共方法都返回一个 HTTP::Response 对象。

Referring the HTTP::Response docs gives this sample:参考HTTP::Response文档给出了这个示例:

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

As far as Perl is concerned, your $artifact variable is a hash reference with a single key/value pair.就 Perl 而言,您的$artifact变量是具有单个键/值对的散列引用。 The URI is embedded in the value, which appears to be JSON. URI 嵌入在值中,该值似乎是 JSON。 You need to extract the value, parse it, and then fetch the URI.您需要提取值,解析它,然后获取 URI。

JSON is a valid subset of YAML, so you can use a YAML module to parse it. JSON 是 YAML 的有效子集,因此您可以使用 YAML 模块来解析它。

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

That said, a leading underscore on a method/attribute name usually mean that they're "private" to the class and shouldn't be used externally.也就是说,方法/属性名称上的前导下划线通常意味着它们对类是“私有的”,不应在外部使用。 Peeking behind the API (which we can't know without knowing where the data came from and what class $artifact is blessed into) is fragile.窥视 API(如果不知道数据来自哪里以及$artifact被祝福到哪个类,我们就无法知道)是脆弱的。

That's not the exact output you get from Dumper, is it?那不是您从 Dumper 获得的确切输出,是吗? If the Dumper output includes a call to bless then it should also include the name of the class that the reference has been blessed into.如果 Dumper 输出包括对bless的调用,那么它还应该包括引用已被祝福到的类的名称。

The naive approach would be this:天真的方法是这样的:

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

But given that what you seem to have there is an object (a blessed hash reference) then there will almost certainly be methods on the class to access the attributes of the object.但是考虑到您似乎拥有一个对象(一个受祝福的哈希引用),那么几乎可以肯定该类上会有方法来访问该对象的属性。 You should use those rather than digging around in the internals of the object.您应该使用它们而不是在对象的内部进行挖掘。

Update: Yes, I missed that the whole of the _content key was a JSON string.更新:是的,我错过了整个_content键是一个 JSON 字符串。 Sorry about that :-/对于那个很抱歉 :-/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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