find a hash value which points to another hash value

Viewed 56

I have an array of hash $ITEM1 as following, couple of the hash value is a pointer 'isEligibleForSuperSaverShipping' => $ITEM1->[0]{'isSNS'} point back to 'isSNS' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ).

How do I print out the value for 'isEligibleForSuperSaverShipping'?

my $ITEM1 = [
          {
            'trackingSince' => 1460340,
            'rootCategory' => 172282,
            'itemWidth' => 178,
            'binding' => 'Personal Computers',
            'availabilityAmazon' => 2,
            'isSNS' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ),
            'launchpad' => $ITEM1->[0]{'isSNS'},
            'format' => undef,
            'isEligibleForSuperSaverShipping' => $ITEM1->[0]{'isSNS'}
          }
        ];
2 Answers

This looks like the output of something such as Data::Dumper, but modified somehow. As you have it written because it needs to reference itself to make itself.

use v5.12;
use warnings;

my $value = bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' );
my $ITEM1 = [
          {
            'trackingSince' => 1460340,
            'rootCategory' => 172282,
            'itemWidth' => 178,
            'binding' => 'Personal Computers',
            'availabilityAmazon' => 2,
            'isSNS' => $value,
            'launchpad' => $value,
            'format' => undef,
            'isEligibleForSuperSaverShipping' => $value,
          }
        ];

use Data::Dumper;

say Dumper( $ITEM1 );

This produces:

$VAR1 = [
          {
            'launchpad' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ),
            'format' => undef,
            'availabilityAmazon' => 2,
            'itemWidth' => 178,
            'trackingSince' => 1460340,
            'isSNS' => $VAR1->[0]{'launchpad'},
            'binding' => 'Personal Computers',
            'isEligibleForSuperSaverShipping' => $VAR1->[0]{'launchpad'},
            'rootCategory' => 172282
          }
        ];

But, this isn't something that you can eval back into Perl because it's self-referential. The variable doesn't even exist yet if you put a my in front of it. Data::Dumper resists re-dumping things it has already seen so it refers back to them. Consider, for instance, having to repeatedly dump the same DateTime object: it can really slow down the process and explode the output size.

You can tell Data::Dumper to not do this:

use Data::Dumper;
$Data::Dumper::Deepcopy = 1;
say Dumper( $ITEM1 );

Now it doesn't make those references:

$VAR1 = [
          {
            'availabilityAmazon' => 2,
            'trackingSince' => 1460340,
            'isSNS' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ),
            'isEligibleForSuperSaverShipping' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ),
            'itemWidth' => 178,
            'launchpad' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ),
            'binding' => 'Personal Computers',
            'format' => undef,
            'rootCategory' => 172282
          }
        ];

But, you should probably be using something different upstream so you aren't playing with Data::Dumper. There are various security problems with Perl modules that recreate objects.

When dumping something obtained from a JSON deserializer, I like to use

print(Data::Dumper->Dump(
   [ $mod->true, $mod->false, $data ],
   [qw( $true $false $data )],
));
$true = bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' );
$false = bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' );
$data = [
          {
            'availabilityAmazon' => 2,
            'isSNS' => $false,
            'launchpad' => $false,
            'rootCategory' => 172282,
            'format' => undef,
            'itemWidth' => 178,
            'isEligibleForSuperSaverShipping' => $false,
            'binding' => 'Personal Computers',
            'trackingSince' => 1460340
          }
        ];

It's more readable that way.

This works for Cpanel::JSON::XS, JSON::XS, JSON::PP and JSON.

Related