Perl - 不是哈希引用或在使用“严格引用”时不能使用字符串(“...”)作为哈希引用

Perl - 不是哈希引用或在使用“严格引用”时不能使用字符串(“...”)作为哈希引用

我正在学习 Perl。我能够使用 Perl 哈希数据结构迭代 JSON 集合,例如使用样本数据。但是,实际数据包含一些导致错误Not a HASH reference或 的元素Can't use string ("...") as a HASH ref while "strict refs" in use

这是给我带来麻烦的有问题数据的简化示例:

{
    "0y7vfr1234": {
        "username": "[email protected]",
        "password": "some-random-password123",
        "uri": "ww1.example.com",
        "index": 14
    },
    "v2rbz1568": {
        "username": "[email protected]",
        "password": "some-random-password125",
        "uri": "ww3.example.com",
        "index": 29
    },
    "active": "0y7vfr1234",
    "0zjk1156": {
        "username": "[email protected]",
        "password": "some-random-password124",
        "uri": "ww2.example.com",
        "index": 38
    },
    "logging": {
        "active": true
    }
}

我只关心具有uri.我想跳过其他的。我该怎么做呢?

在尝试了数十种不起作用的方法(并且只会导致新的或不同的错误)之后,以下是我最终解决这些错误的方法。但是,我认为有比使用ref().

#!/usr/bin/perl
use JSON;
use utf8;
use Data::Dumper;
use strict; use warnings;

my $data = '{
        "0y7vfr1234": {
            "username": "[email protected]",
            "password": "some-random-password123",
            "uri": "ww1.example.com",
            "index": 14
        },
        "v2rbz1568": {
            "username": "[email protected]",
            "password": "some-random-password125",
            "uri": "ww3.example.com",
            "index": 29
        },
        "active": "0y7vfr1234",
        "0zjk1156": {
            "username": "[email protected]",
            "password": "some-random-password124",
            "uri": "ww2.example.com",
            "index": 38
        },
        "logging": {
            "active": true
        }
    }';

my $json = decode_json($data);

foreach my $key (keys %$json) {

    if ( ref( $json->{$key} ) !~ m/HASH/ ) {
            print "[" . ref( $json->{$key} ) . "]: skipping\n";
            next;
    }

    if ( ! exists $json->{$key}->{uri} ) {
        print "Not a server. It's type is:  [" . ref($json->{$key}) . "]\n";
        print "Without curly braces: $json->$key\n";
        print Dumper($json->{$key});
        print "With curly braces: $json->{$key}\n";
        next;
    }

    print "checking $json->{$key}->{uri}\n";
    # do some other stuff
}

代码或多或少按原样工作,但我对它不满意......或者我对它的理解。

我的问题是:

  1. 迭代像我的 JSON 这样的“混合”数据而不遇到错误的正确方法是什么?
  2. 显示有关我跳过的元素的一些信息的好方法是什么?我在代码中尝试了各种东西(数据转储器、不带大括号的打印等),但没有一个令人满意。有没有更好的方法可以显示有关跳过的内容的信息(当然不会导致错误)?
  3. 为什么上面的代码$json->{$key}->{uri}在没有箭头的情况下也能正常工作:$json->{$key}{uri}

我在 Linux 上使用 perl 5 版本 30。

答案1

像这样:

#!/usr/bin/perl   
use JSON; use utf8;
use strict; use warnings;

my $data = '{
        "0y7vfr1234": {
            "username": "[email protected]",
            "password": "some-random-password123",
            "uri": "ww1.example.com",
            "index": 14
        },
        "v2rbz1568": {
            "username": "[email protected]",
            "password": "some-random-password125",
            "uri": "ww3.example.com",
            "index": 29
        },
        "active": "0y7vfr1234",
        "0zjk1156": {
            "username": "[email protected]",
            "password": "some-random-password124",
            "uri": "ww2.example.com",
            "index": 38
        },
        "logging": {
            "active": true
        }
}';   
my $json = decode_json($data);
while (my ($key, $value) = each(%$json)) {
    next unless ref $value;            # skip if $value isn't a ref
    next if scalar (keys %$value) < 2;  # skip if the numbers of HASH keys < 2
    print "$value->{uri}\n";
}

相关内容