Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: Making JSON::{PP,XS} not decode true/false to JSON::{PP,XS}::Boolean objects (PL_sv_yes PL_sv_no !!1 !!0 )

by Anonymous Monk
on Oct 15, 2013 at 01:49 UTC ( [id://1058223]=note: print w/replies, xml ) Need Help??


in reply to Making JSON::{PP,XS} not decode true/false to JSON::{PP,XS}::Boolean objects

Edit the XS version to use &PL_sv_yes and & PL_sv_no

Edit the PP version to use !!1 and !!0 respectively

Replies are listed 'Best First'.
Re^2: Making JSON::{PP,XS} not decode true/false to JSON::{PP,XS}::Boolean objects (PL_sv_yes PL_sv_no !!1 !!0 )
by sedusedan (Monk) on Oct 15, 2013 at 02:11 UTC
    Yes of course :) I was hoping that there would be a way to do it without going to the source.
      I was hoping that there would be a way to do it without going to the source.

      How were you going to figure this out without going to the source?

      Going to the source, I saw that it is possible to change what JSON::XS returns for 'true' and 'false', if you get your stuff run at the right time. For example:

      use XSLoader; BEGIN { my $load = \&XSLoader::load; sub load { *JSON::XS::true = *true; *JSON::XS::false = *false; goto &$load; } *XSLoader::load = *load; our( $true, $false ) = \( 1, 0 ); sub true() { $true } sub false() { $false } } use JSON::XS(); print ref($_), ' ', $_, $/ for @{ JSON::XS->new()->decode('["0","1",true,false]') };

      But JSON::XS blithely assumes that $JSON::XS::true (and ...false) will contain references. If you adjust my code above so that they don't contain references, then as soon as you try to decode JSON containing 'true' or 'false', you'll get a core dump.

      If I were you, I'd just use something much simpler like JSON::Tiny. And I'd file a patch request to have "my $TRUE" changed to "our $TRUE", etc.

      - tye        

        If I were you, I'd just use something much simpler like JSON::Tiny. And I'd file a patch request to have "my $TRUE" changed to "our $TRUE", etc.

        Minimally, I've implemented this in JSON::Tiny version 0.33, uploaded to CPAN just a few minutes ago. my $TRUE... is now our $TRUE, so that users may explicitly override the return value for Booleans. The same goes for my $FALSE.

        If there is sufficient call for it, I might also provide additional flexibility in _encode_value() by changing this line: return $value  ? 'true' : 'false' if $ref eq 'JSON::Tiny::_Bool'; to something like return $value  ? 'true' : 'false' if $ref eq $BOOL_CLASS; # A package global. Once we go too far down that road, however, people are going to start asking that $TRUE, $FALSE, and $BOOL_CLASS be implemented as object attributes for the JSON::Tiny object so that they can be manipulated on a per-instance basis... and that leads to becoming less '::Tiny'. ;)

        For now just consider the following code:

        use JSON::Tiny; $JSON::Tiny::FALSE = 0; $JSON::Tiny::TRUE = 1; my $j = JSON::Tiny->new(); # ... Booleans in JSON being decoded now return 0 and 1 instead of # JSON::Tiny::Bool objects

        Update: Version 0.34 adds some tests and documentation on this advanced feature.


        Dave

        How were you going to figure this out without going to the source?

        What I meant was without modifying the source.

        That's a bit unfortunate about having to use references instead of 1/0 (or !!1 / !!0). I still prefer JSON::XS though, for the speed, and if JSON::XS + Data::Clean::FromJSON proves to be not fast enough later on, I'll create an (initially private) fork of JSON::XS.

        Thanks!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1058223]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-03-28 20:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found