CodeQuestor
CodeQuestor

Reputation: 911

perl JSON decode is not giving expected result

I have below JSON input -

{"links":{"self":"/some/path"},"data": [{"type":"some_service","id":"foo","attributes": {"created":true,"active":true,"suspended":false}}, {"type":"some_service","id":"dummy","attributes":{"created":false}}]}

I am using below code -

use strict;
use warnings;
use JSON::XS;
use Data::Dumper;

my $result = decode_json($input);
print Dumper($result) . "\n";

But i am getting below output -

$VAR1 = {
      'data' => [
                  {
                    'attributes' => {
                                      'active' => bless( do{\(my $o = 1)}, 'JSON::XS::Boolean' ),
                                      'created' => $VAR1->{'data'}[0]{'attributes'}{'active'},
                                      'suspended' => bless( do{\(my $o = 0)}, 'JSON::XS::Boolean' )
                                    },
                    'id' => 'foo',
                    'type' => 'some_service'
                  },
                  {
                    'id' => 'dummy',
                    'attributes' => {
                                      'created' => $VAR1->{'data'}[0]{'attributes'}{'suspended'}
                                    },
                    'type' => 'some_service'
                  }
                ],
      'links' => {
                   'self' => '/some/path'
                 }
    };

Looks like the value in 'created' is $VAR1->{'data'}[0]{'attributes'}{'active'} which does not seems to be accurate and same happens at other places too.

Am i missing somewhere in code or the JSON input has some error? Kindly provide your suggestions.

Upvotes: 1

Views: 768

Answers (2)

ikegami
ikegami

Reputation: 385916

Why do you think it's inaccurate? If we look at the JSON, active and created both have the same value: true. Maybe you'll find it clearer to dump the structure as follows:

use JSON::XS     qw( decode_json );
use Data::Dumper qw( );

my $data = decode_json(<<'__EOI__');
{"links":{"self":"/some/path"},"data [{"type":"some_service","id":"foo","attributes": {"created":true,"active":true,"suspended":false}}, {"type":"some_service","id":"dummy","attributes":{"created":false}}]}
__EOI__

print(Data::Dumper->Dump(
   [ JSON::XS::true, JSON::XS::false, $data ],
   [qw( true false data )],
));

Output:

$true = bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' );
$false = bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' );
$data = {
          'data' => [
                      {
                        'attributes' => {
                                          'active' => $true,
                                          'created' => $true,
                                          'suspended' => $false
                                        },
                        'id' => 'foo',
                        'type' => 'some_service'
                      },
                      {
                        'attributes' => {
                                          'created' => $false
                                        },
                        'id' => 'dummy',
                        'type' => 'some_service'
                      }
                    ],
          'links' => {
                       'self' => '/some/path'
                     }
        };

Upvotes: 0

Matt Healy
Matt Healy

Reputation: 18531

The JSON decoder is just "mapping/pointing" the values to previous values that have already been parsed. You can see your first created points to

$VAR1->{'data'}[0]{'attributes'}{'active'},

, the value of which is true, just like active should be. You are looking at the Data::Dumper representation of the hash array.

If you were to retrieve an element from the Perl variable, you would find that it matches up with your original input:

print $result->{"data"}[0]->{"attributes"}->{"created"}; # prints 1

To print the Data::Dumper output without this occurring, simply set this flag in your script:

$Data::Dumper::Deepcopy = 1;

Upvotes: 3

Related Questions