Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

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 ( [id://1058225]=note: print w/replies, xml ) Need Help??


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

Yes of course :) I was hoping that there would be a way to do it without going to the source.
  • Comment on Re^2: Making JSON::{PP,XS} not decode true/false to JSON::{PP,XS}::Boolean objects (PL_sv_yes PL_sv_no !!1 !!0 )

Replies are listed 'Best First'.
Re^3: Making JSON::{PP,XS} not decode true/false to JSON::{PP,XS}::Boolean objects (source)
by tye (Sage) on Oct 15, 2013 at 03:23 UTC
    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

        Thanks!

        Since, for a boolean type, it is reasonable to implement it as a ref to a scalar (and that is how it has been done over and over in several different JSON modules), I'd just treat a reference to a scalar as a boolean. The only change required is using reftype() or $ref =~ /SCALAR/, as ref() returning exactly "SCALAR" is already handled that way.

        - tye        

        Hmmm, what to do .....

        $JSON::Tiny::FALSE = \'0FALSE'; $JSON::Tiny::TRUE = \'1TRUE'; $JSON::Tiny::FALSE = !!0; $JSON::Tiny::TRUE = !!1; $JSON::Tiny::FALSE = Scalar::Util::dualvar( 0, '0false'); $JSON::Tiny::TRUE = Scalar::Util::dualvar( 1, '1true');
      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://1058225]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (5)
As of 2024-04-24 08:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found