fREWdiculous!
20 Jan
Background: dates in our database automatically get “inflated” to DateTime objects. That works pretty much perfectly. We use JSON to serialize all of our objects to go to our JavaScript stuff on the client side. The way that works is basically like the following:
1 2 3 4 5 6 7 8 9 10 |
which expands to:
1 2 3 4 5 | { id => 1, name => 'frew', when_created => DateTime->new(...), # <-- not ok } |
Problematically, DateTime has no TO_JSON method. I see two solutions to this, both of which kinda suck.
I could do something like:
1 2 3 |
but we all know that Monkey Patching is Sketch Towne City. Since perl is a prototypical language there is certainly a way to do something like:
1 2 | my $f = DateTime->now; $f::TO_JSON = sub { shift->ymd }; |
but I couldn’t really figure out how to do it. And even if I could that (probably easy with Class::MOP) I’d still have to make hooks to do that to all to all of our DateTime objects (which still sucks.) And then I could effectively do the same thing…
1 2 3 4 |
And then do some kind of trickery in DBIC-land to make the DateTime instantiation able to use other classes. But that’s not as simple as it might sound (due to design issues in DBIC that are not easy to solve as far as I can see.)
I’m pretty sure that there is a good solution that I’m missing. What is it? Can anyone tell me?
3 Responses for "What is the right way to serialize X object generically?"
Don’t monkey patch…
If you have defined your own private serialisation scheme, then you can define your own set of special casing.
my @SPECIAL = (
[
'DateTime',
sub { to json },
sub { from_json } ],
],
[
...
],
);
then later…
if ( $instance->can(‘TO_JSON’) ) {
return $instance->TO_JSON;
}
my $special = first {
$instance->isa($_->[0])
} @SPECIAL;
if ( $special ) {
return $special->[1]->( $instance );
}
Crap, broken indenting…
Set up a typemap to reuse the Storable hooks of a class. See KiokuDB::TypeMap::Default and KiokuDB::TypeMap::Entry::Passthrough and ack for DateTime.
Leave a reply