Prompted by a recent question on PerlMonks, I’ve been thinking a bit recently on marshalling and unmarshalling Perl objects. If you’re happy using Data::Dumper’s format, then it’s trivial, but today we’re looking at JSON.
If you just want to encode your objects as JSON, that’s very easy. Just add a TO_JSON
method to all your classes. This can be done in a role to eliminate duplication, and in most cases can be as simple as:
The difficulty comes in going the other direction.
Here’s a quick example using Zydeco to encode a basic object with a couple of nested objects in JSON and fail at decoding it:
The script output is shown in the __END__
section.
So what goes wrong? When we attempt to decode the JSON, the Farm class complains that for the fields attribute, you’re passing it an arrayref of hashrefs instead of an arrayref of Field objects.
This is pretty easy to solve. We just need to define a coercion from ArrayRef[HashRef] to ArrayRef[Field]. Because Types::Standard is somewhat smart about coercions, it is sufficient to define a coercion from HashRef to Field and let Types::Standard worry about the rest.
Hooray! It works!
Here’s a final example showing some more advanced features for object creation, coercion, marshalling, and unmarshalling.