Search code examples
arraysjsonperl

Accessing array elements in a decoded JSON hash


I have the following code:

#!/opt/local/bin/perl

use strict;
use warnings;

use JSON::XS qw/decode_json/;

my $api_response = '{"user":{"id":14897,"data":["foo", "bar", "baz"]}}';
my $user = decode_json($api_response);
$user = $user->{user};

my @data = $user->{data};

print($user->{id}, "\n");  # output: 14897
print("@data", "\n");      # output: ARRAY(0x14200d9b8)
print($data[0], "\n");     # output: ARRAY(0x14200d9b8) why???
print($data[0][0], "\n");  # output: foo

This is working fine for me, but it took me a while to figure out that I have to go 2 levels deep into $data which, to my eyes, should represent a simple array of strings. Is this expected behaviour, or is there something wrong with my code?


Solution

  • Scalars such as hash elements can't be arrays or hashes. But we can store references to arrays hashes and hashes in them. This is the case here.

    my @data = $user->{data};
    
    say "@data";
    say $data[0];
    

    should be

    my $data = $user->{data};
    
    say "@$data";
    say $data->[0];
    

    Alternatives:

    postfix circumfix circumfix (curlies omitted)
    my $data =
    $user->{data};

    say join " ", $data->@*;
    say $data->[0];
    my $data =
    $user->{data};

    say "@{ $data }";
    say ${ $data }[0];
    my $data =
    $user->{data};

    say "@$data";
    say $$data[0];

    See Perl Dereferencing Syntax