Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

keys in reference experimental or reference is deprecated

by demichi (Beadle)
on Nov 17, 2016 at 16:08 UTC ( [id://1176056]=perlquestion: print w/replies, xml ) Need Help??

demichi has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I had a nice code working but after testing on a differnt Perl Version I get some errors.

#$json_decoded is a refrence #$json_decoded = # { # # "data" : [ { # # "storageDeviceId" : "800000050679", # # "model" : "modelname", # # "serialNumber" : 12346, # # "svpIp" : "10.1.1.1" # # } ] # #} for my $key1 (keys $json_decoded) { # key1 = data for my $key2 (keys $json_decoded->{$key1}) { # key2 = 0 .. x for my $key3 (keys $json_decoded->{$key1}[$key2]) { # key3 = storageDeviceId,model,etc $REST_storage{$key3} = $json_decoded->{$key1}[ +$key2]{$key3}; } }

That worked fine on server 1. On server 2 I got message "keys on reference is experimental" 3 times (on every line with "keys ...") and I learned to use ...

 keys %{ $json_decoded }

instead of ...

keys $json_decoded

This works on both systems.

But when I change to ...

 keys %{ $json_decoded->{$key1} }

instead of ...

keys $json_decoded->{$key1}

... I get the message "Script died: Not a HASH reference at".

Can you help me with the right syntax please to get it run on every Perl version?

Thanks & regards

de Michi

Replies are listed 'Best First'.
Re: keys in reference experimental or reference is deprecated
by Corion (Patriarch) on Nov 17, 2016 at 16:13 UTC

    Maybe you can show us what is in $json_decoded and $key1 and $json_decoded->{$key1}?

    The syntax that will work on all versions of Perl is keys %{ $json_decoded->{$key1} }, provided that $json_decoded is a hash reference.

    I note that your usage of $key2 is inconsistent with its name - you're using it as array index, not as a hash key:

    for my $key3 (keys $json_decoded->{$key1}[$key2])

    This is a change allowed since Perl 5.12, but I find it somewhat confusing still.

    I guess the best approach is to reduce your data structure and code to a short, self-contained example that still exhibits the problem and then to post that together with the Perl versions and their output.

      Ok, here the working code on 5.16.3 with output:

      print Dumper $json_decoded; for my $key1 (keys $json_decoded) { # key1 = data print "key 1: $key1 + $json_decoded->{$key1}\n"; for my $key2 (keys $json_decoded->{$key1}) { # key2 = 0 .. x print "key 2: $key2 + $json_decoded->{$key1}[$key +2]\n"; for my $key3 (keys $json_decoded->{$key1}[$key2]) { # key3 = storageDeviceId,model,etc print "key 3: $key3 + $json_decoded->{$key1}[ +$key2]{$key3}\n"; $REST_storage{$key3} = $json_decoded->{$key1}[ +$key2]{$key3}; } } }

      Output:

      $VAR1 = { 'data' => [ { 'svpIp' => '10.1.1.1', 'model' => 'xyz', 'storageDeviceId' => '800000058068', 'serialNumber' => 58068 } ] }; key 1: data + ARRAY(0x2c79f78) key 2: 0 + HASH(0x321a140) key 3: svpIp + 10.1.1.1 key 3: model + xyz key 3: storageDeviceId + 800000058068 key 3: serialNumber + 58068

      Does this help?

        So you have a version that works but did not apply the changes that I suggested. When I mentioned a self-contained example, I meant something like the following below, which does not need any editing to be runnable:

        use strict; use Data::Dumper; my %REST_storage; my $json_decoded = { 'data' => [ { 'svpIp' => '10.1.1.1', 'model' => 'xyz', 'storageDeviceId' => '800000058068', 'serialNumber' => 58068 } ] }; print Dumper $json_decoded; for my $key1 (keys %$json_decoded) { # key1 = data print "key 1: $key1 + $json_decoded->{$key1}\n"; for my $key2 (keys @{ $json_decoded->{$key1} }) { # key2 = 0 .. x print "key 2: $key2 + $json_decoded->{$key1}[$key +2]\n"; for my $key3 (keys %{ $json_decoded->{$key1}[$key2 +] }) { # key3 = storageDeviceId,model,etc print "key 3: $key3 + $json_decoded->{$key1}[ +$key2]{$key3}\n"; $REST_storage{$key3} = $json_decoded->{$key1}[ +$key2]{$key3}; } } }

        That code is explicit about what it uses instead of relying on keys on a reference still working.

        Maybe you can look at this code and determine whether it applies to your situation or not. I didn't try this with a recent Perl version.

        Does this help?

        Not as much as it could; because its data is not bundled with the code it is not a short, self-contained example. To provide a complete answer someone would have to do the extra work of reverse-engineering your data-structure to figure out what it looked like in the first place. And frankly, many potential answers will not be written, or will be less helpful than they could have been because the prospect of extra, error-prone work of reverse-engineering sample data from code that is known to be buggy discourages people from helping, particularly when it would not be much effort for the person asking to provide a small data sample in the first place.

        Your code snippet could have been like this:

        use strict; use warnings; use JSON qw(decode_json); my $json_decoded = decode_json(do {local $/ = undef; <DATA>}); #...your code goes here... __DATA__ {"foo":"bar", "baz":["buzz":1] }

        ...or...

        use strict; use warnings; my $json_decoded = {foo => 'bar', baz => ['buzz', 1]}; # Your code goes here...

        In either case we would have all the facts in front of us, and could run your sample code and see the output you are seeing.

        At any rate, see my answer at a higher-level in this thread for an explanation of the benefit of diagnostics when a terse error message feels cryptic.


        Dave

Re: keys in reference experimental or reference is deprecated
by davido (Cardinal) on Nov 17, 2016 at 16:19 UTC

    Please provide a fully self-contained code sample that includes its own small sample data-set, that will compile and run, and that will demonstrate the behavior you are describing. It should be possible to demonstrate both examples.

    If you add use diagnostics; to your script you will get a more thorough explanation of what is meant by each of the error messages. As I glanced over perldiag, I saw this:

    Can't use a hash as a reference (F) You tried to use a hash as a reference, as in %foo->{"bar"} or %$r +ef->{"hello"} . Versions of perl <= 5.22.0 used to allow this syntax, + but shouldn't have. This was deprecated in perl 5.6.1.

    That is probably a good explanation of what you are seeing in that second error message.


    Dave

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1176056]
Approved by stevieb
Front-paged by kcott
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (8)
As of 2024-04-25 11:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found