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

Hi,

I've been hitting a problem, whereas JSON::true() and JSON::false don't always return a correct true or false value (they give a "null" value instead). This only happens under mod_perl

So, after some reading someone suggested using JSON::Tiny instead, as it supposedly works better under threaded processes. I've tried:

print to_json($values);

and even:

print encode_json($values);

but both of those fatal:

encountered object '0', but neither allow_blessed, convert_blessed nor allow_tags settings are enabled (or TO_JSON/FREEZE method missing) at /usr/local/share/perl5/JSON.pm line 154.


I'm a bit confused as to why its doing this :(

Any suggestions?

BTW: I have managed to get them working (I hope) using the standard JSON module, and using \0 and \1 for false/true, and so far it seems to be working. Would prefer to find a nicer way to do it though :)

TIA

Andy

Replies are listed 'Best First'.
Re: JSON.pm and mod_perl
by Your Mother (Archbishop) on Mar 30, 2016 at 12:24 UTC
    I'm a bit confused as to why its doing this :(

    Because you're sending a JSON::Tiny::_Bool object to be processed by JSON is my guess. It can handle its own JSON::Booleans but not the objects from JSON::Tiny.

    If you want to switch, you will have to remove *all* of the old code. And just to back up and check: you are restarting the apache httpd on all code changes, right? And while you describe the outcome/problem, you haven't shown any code to duplicate it. How were you writing true and false before the perfectly acceptable \1 and \0? I'm unsure where threading comes into this as a problem. Where did you hear that you should use JSON::Tiny instead? (It wouldn't even install for me.)

      Thanks for the reply. So, with my old code (just using the JSON module), I was using:

      True and false:
      $values->{foo} = JSON::true(); $values->{foo2} = JSON::false();
      ...and then encoding them with:

      use JSON; my $json = JSON->new; $json->allow_blessed(1); print $json->encode($values);


      With the new code (using just JSON::Tiny), I was simply doing:
      $values->{foo} = JSON::Tiny->true; $values->{foo2} = JSON::Tiny->false;
      ..and then to encode:

      print encode_json($values);

      ..and also tried:

      print to_json($values);

      I read about the threading issue here: http://www.perlmonks.org/?node_id=1021294

      Cheers

      Andy

        Hmmm. Real bug, looks like(?). I don't have a modperl install to play with though so can't comment on that.

        Since the string allow_blessed does not appear in JSON::Tiny I have to assume you are still loading JSON somewhere. You'll either need to comb through code/%INC to find and remove it or perhaps fully qualify your calls to JSON::Tiny::encode_json() etc.

        Sidenote: you do not need allow_blessed to be true if working with JSON bools. Setting it true in general is probably a bad practice. Throwing around objects can mean revealing much more information than intended. You might, for example, send a list of user objects to the webpage via ajax and end up showing private information that is in the object like addresses or real names when you just meant to show username and webpage.

        perl -MJSON -le 'print encode_json({o=>JSON::true()})' {"o":true}
Re: JSON.pm and mod_perl
by Myrddin Wyllt (Hermit) on Mar 30, 2016 at 13:45 UTC

    I remember there was a problem with boolean values in JSON::XS a couple of years ago (version 3.01 broke compatibility with JSON). As far as I know, these issues still exist.

    The JSON module will use JSON::XS if it is installed, or fall back to the (slower) pure perl JSON::PP if it isn't. If you have a version of JSON::XS higher than 3.01 installed, it may be the root cause of your problem.

    The solution I adopted when I had boolean-related problems with JSON in late 2014 was to switch to JSON::MaybeXS and Cpanel::JSON::XS, which are pretty much drop-in replacements for JSON / JSON::XS with boolean compatibility and a couple of other things (including threading) tidied up. Touch wood, I've had no problems since making the change.

      Thanks - I'll give those a go :)
Re: JSON.pm and mod_perl
by Anonymous Monk on Mar 30, 2016 at 07:00 UTC
    So the question is now?
      Hi,

      A couple of questions really :)

      1) Why did I get that error with JSON::Tiny? With the JSON module, I do:
      use JSON; my $json = JSON->new; $json->allow_blessed(1); print $json->encode($values);
      ... but I couldn't find a way to "allow_blessed" when using the JSON::Tiny module

      2) If I decide to keep the JSON module... with the \0 and \1 variables now, will the rest of the JSON be thread safe? (I don't want other stuff getting mixed up in the returned json :))

      TIA

      Andy