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";
}

관련 정보