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

おすすめ記事