use strict
とを常にオンにしていた場合use warnings
、宣言されていない変数に関する一連の致命的なエラーが発生していたでしょう。最初にそれらを修正しましょう:
use strict;
use warnings;
use JSON;
my $test='{
"name":"Tony",
"body":[ {
"arms":["hands:fingers", "muscles:biceps"],
"stomach":["abs:sixpack", "noabs:onepack"]
},
{
"arms":["fingers:nails", "knuckles:sharp"],
"stomach":["abs:gut", "noabs:liquor"]
}]
}';
my $decoded = decode_json($test);
my @layer1 = @{ $decoded->{'body'} };
foreach ( @layer1 ) {
my @layer2 = $_->{$decoded->{'arms'} };
foreach( @layer2 ) {
print $_->{$decoded->{'hands'}} . "\n";
}
}
これで、少なくともコードは でコンパイルされuse strict
ます。しかし、それはたくさんの警告を発します:
Use of uninitialized value in hash element at js.pl line 21.
Use of uninitialized value in hash element at js.pl line 23.
Use of uninitialized value in concatenation (.) or string at js.pl line 23.
Use of uninitialized value in hash element at js.pl line 21.
Use of uninitialized value in hash element at js.pl line 23.
Use of uninitialized value in concatenation (.) or string at js.pl line 23.
これらの警告は有用な情報です。なんと便利なツールuse warnings
でしょう!
最初のものを見てみましょう: js.pl 行 21 のハッシュ要素での初期化されていない値の使用。
21 行目は次のとおりです。
my @layer2 = $_->{$decoded->{'arms'} };
このループで$_
は、外側の配列 ( @{ $decoded->{body} }
) の各要素に が設定されます。その配列の各要素はハッシュ参照です。あなたがしているのは、ハッシュarms
の最初のレベルのキーを、配列内の要素が指すハッシュへのキーとして使用しようとしていることです。そのキーはこれらのハッシュには存在しないため、初期化されていない値に関する警告が表示されます。
欲しいものを手に入れるために必要なのは
my @layer2 = @{ $_->{arms} };
3 番目の層はより複雑です。ハッシュの配列ではなく、コロンで区切られた文字列の配列です。そのループでは、必要のない文字列を見つけるまで捨てることができます。hands
foreach( @layer2 ) {
next unless /^hands:/;
my ( $thing, $other_thing ) = split /:/, $_;
print $other_thing, "\n";
}
修正されたスクリプトは次のとおりです。
use strict;
use warnings;
use JSON;
my $test='{
"name":"Tony",
"body":[ {
"arms":["hands:fingers", "muscles:biceps"],
"stomach":["abs:sixpack", "noabs:onepack"]
},
{
"arms":["fingers:nails", "knuckles:sharp"],
"stomach":["abs:gut", "noabs:liquor"]
}]
}';
my $decoded = decode_json($test);
my @layer1 = @{ $decoded->{'body'} };
foreach ( @layer1 ) {
my @layer2 = @{ $_->{arms} };
foreach( @layer2 ) {
next unless /^hands:/;
my ( $thing, $other_thing ) = split /:/, $_;
print $other_thing, "\n";
}
}
出力:
fingers
Perl での複雑な構造の操作の詳細については、次を参照してください。
それらを読んで、もう一度読んでから、コードを書きます。それからそれらをもう一度読んでください。