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

Hi - I was updating this script at work in a totally different section to add an exception. When I went to test run it, I received an error: Experimental keys on scalar is now forbidden at line 339. I went to that part of the script and fixed it by dereferencing. my @result = keys $results->{$ip}; changed to my @result = keys %{$results->{$ip}}; However, when I re-ran the script, I got the error: Can't use an undefined value as a SCALAR reference at line 335. I then tried to change that part of the code by removing the ${} that surrounded $client->do_task(...) based on a suggestion from someone else. I have no idea about json and using it, and I have no idea about what this part of the code does. When I re-ran the script again, I then got the error: malformed JSON string, neither tag, array, object, number, string or atom, at character offset 0 (before "(end of string)") at line 334. I am now not sure if I fixed the Experimental Keys error correctly or not as I am not understanding why the other stuff is breaking when fixing it. Original code, without any fixes, is below
329 print "\nRunning isok on ip $ip\n"; + + 330 + + 331 my $client = Gearman::Client->new; + + 332 $client->job_servers('<location>'); + 333 + + 334 my $results = decode_json( + + 335 ${ $client->do_task( + + 336 'isok_production', encode_json({ isok_payload => $ip + }) + 337 )} + + 338 ); + + 339 my @result = keys $results->{$ip};
Any help in understanding these errors and how to correct would be appreciated. Thanks

Replies are listed 'Best First'.
Re: Fixing Experimental Keys error caused other errors to occur
by Fletch (Bishop) on May 05, 2021 at 19:02 UTC

    Looking at the docs for Gearman::Client that do_task method returns an undef on failure or a scalar ref to the result value on success. You need to check for that failure (and/or other possible failures; handwavy sample follows but you could go even further checking if decode_json throws an error) before you try and dereference it to decode whatever JSON into something you can treat as a hashref.

    my $result = $client->do_task( ... ); if( not defined $result ) { ## Presumably there may be some other information about the failure +but I don't ## see offhand how to retrieve that; but that's a good thing to incl +ude in your ## error message here die "isok not ok for ip '$ip'!\n"; } my $json_result = decode_json( ${ $result } ); if( not ref $json_result or not ref $json_result->{ $ip } or ref $json +_result->{$ip} ne q{HASH} ) { die "Did not get back the hashref expected for '$ip'\n"; } my @result = keys %{ $json_result->{ $ip } }

    Edit: Tweaked variable name last line. Derp. And expanded on description of method's return value. MOAR EDITS

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      This helped me to figure out there had to be something wrong in our dev environment. It script died at the first part but we checked that Gearman was up and running fine. I moved the script to non-dev but still ran it on QA db - the script then passed the first debug but died at the JSON debug. I then ran the script on a non-QA db ticket and it worked. So thanks for the debug help!
Re: Fixing Experimental Keys error caused other errors to occur
by AnomalousMonk (Archbishop) on May 05, 2021 at 22:00 UTC
    I am now not sure if I fixed the Experimental Keys error correctly or not as I am not understanding why the other stuff is breaking when fixing it.

    Just FYI, my speculative (since I can't verify all these assertions) explanation of the chain of failures you're seeing is:

    1. The Experimental keys on scalar is now forbidden ... error from the
          my @result = keys $results->{$ip};
      statement is a compile time error; no code is actually run.
    2. Once the ... keys on scalar ... error is fixed, the code can compile and run and produces the Can't use an undefined value as a SCALAR reference ... run time error from the
          ${ $client->do_task(...) }
      expression, and execution stops.
    3. If the ... undefined value as a SCALAR reference ... error is fixed, the code runs on until it hits the ... malformed JSON string ... error (which may be a warning rather than a fatal error; I haven't checked).
    Again, please be aware that this explanation is largely speculative.
    (Update: And Fletch's suggestion that the return value of each operation be checked to be as expected and has no object/class/module error status associated with it is an excellent BP IMHO. :)


    Give a man a fish:  <%-{-{-{-<