[ACCEPTED]-How to convert Perl objects into JSON and vice versa-json

Accepted answer
Score: 22

The warning tells you most of what is wrong. Unless 39 you tell JSON how to handle blessed references(Perl 38 objects), JSON handles only un-blessed data 37 structures.

You can convert_blessed and you can allow_blessed. For allow_blessed, it 36 says:

If $enable is false (the default), then encode 35 will throw an exception when it encounters 34 a blessed object.

Point is an object class, thus 33 an instance of Point is a blessed reference, and 32 thus the default for JSON is to throw an exception.

If 31 you enable convert_blessed, it will call a TO_JSON method on your 30 object. With simple objects like Point (ones that contain 29 no blessed members), you can do that as 28 easily as:

sub TO_JSON { return { %{ shift() } }; }

If you have to descend a structure, it 27 will get a lot hairier.


Somebody in the comments 26 below said that I didn't cover how to get 25 objects out of JSON.

The basics are simple. So 24 here goes

my $object = bless( JSON->new->decode( $json_string ), 'ClassIWant' );

I mainly covered the part that 23 prevents you from simply serializing a blessed object 22 into JSON.

The basics of deserialization 21 are simple, just like the basics of serialization 20 are simple--once you know the trick. There 19 is no error in the way, there is just the 18 task of finding what you need and blessing 17 it into the right class.

If you want to 16 have code coupled to the objects, then you'll 15 know what has to be blessed and what it 14 will have to be blessed into. If you want 13 totally decoupled code, this is no harder or easier in Perl than it is in JavaScript itself.

You're going to 12 have to serialize a marker in the JSON. If I need 11 something like this, I will insert a '__CLASS__' field 10 into the blessed objects. And when deserializing, I 9 will descend through the structure and bless 8 everything like this:

 bless( $ref, delete $ref->{__CLASS__} );

But as I said, this 7 is no easier or harder in Perl, because 6 JSON presents the same challenge to all 5 languages.

As Schwern suggested in his comment 4 up top, YAML is much better built for serializing 3 and deserializing objects, because it has 2 notation for it. JSON gives you associative arrays 1 or arrays.

Score: 5

Did you try reading the JSON documentation on the allow_blessed and convert_blessed options, as 8 suggested by the error message? That should 7 explain how to convert a Perl object to 6 JSON.

Going the other way is harder, as JSON 5 isn't YAML, and wasn't designed to be deserialized 4 into a class-based object system like Perl's. You 3 could experiment with the filter_json_object or filter_json_single_key_object options, or 2 you could post-process the decoded JSON 1 and create the objects yourself.

Score: 4

You need JSYNC.

use JSYNC;
use Point;
my $p = Point->new;
$p->X(20);
$p->Y(30);

my $jsync = JSYNC::dump($p, {pretty => 1});

{
   "!" : "!perl/hash:Point",
   "_x" : "20",
   "_y" : "30"
}

0

Score: 2

You may find it useful to convert your classes 2 to Moose and use MooseX::Storage to serialize and deserialize 1 them.

More Related questions