--- JSON-XS/XS.pm 2007/07/02 00:29:38 1.50 +++ JSON-XS/XS.pm 2007/07/02 01:12:27 1.51 @@ -350,6 +350,79 @@ If C<$enable> is false, then the C setting will decide what to do when a blessed object is found. +=item $json = $json->filter_json_object ([$coderef]) + +When C<$coderef> is specified, it will be called from C each +time it decodes a JSON object. The only argument is a reference to the +newly-created hash. If the code references returns a single scalar (which +need not be a reference), this value (i.e. a copy of that scalar to avoid +aliasing) is inserted into the deserialised data structure. If it returns +an empty list (NOTE: I C, which is a valid scalar), the +original deserialised hash will be inserted. This setting can slow down +decoding considerably. + +When C<$coderef> is omitted or undefined, C will not change the +deserialised hash in any way. This is maximally fast. + +Example, convert all JSON objects into the integer 5: + + my $js = JSON::XS->new->filter_json_object (sub { 5 }); + # returns [5] + $js->decode ('[{}]') + # throw an exception because allow_nonref is not enabled: + $js->decode ('{"a":1, "b":2}'); + +=item $json = $json->filter_json_single_key_object ([$coderef]) + +Works like C, but is only called for JSON objects +having only a single key. + +This C<$coderef> is called before the one specified via +C, if any. If it returns something, that will be +inserted into the data structure. If it returns nothing, the callback +from C will be called next. If you want to force +insertion of single-key objects even in the presence of a mutating +C callback, simply return the passed hash. + +As this callback gets called less often then the C +one, decoding speed will not usually suffer as much. Therefore, single-key +objects make excellent targets to serialise Perl objects into, especially +as single-key JSON objects are as close to the type-tagged value concept +as JSON gets (its basically an ID/VALUE tuple). Of course, JSON does not +support this in any way, so you need to make sure your data never looks +like a serialised Perl hash. + +Typical names for the single object key are C<__class_whatever__>, or +C<$__dollars_are_rarely_used__$> or C<}ugly_brace_placement>, or even +things like C<__class_md5sum(classname)__>, to reduce the risk of clashing +with real hashes. + +Example, decode JSON objects of the form C<< { "__widget__" => } >> +into the corresponding C<< $WIDGET{} >> object: + + # return whatever is in $WIDGET{5}: + JSON::XS + ->new + ->filter_json_single_key_object (sub { + exists $_[0]{__widget__} + ? $WIDGET{ $_[0]{__widget__} } + : () + }) + ->decode ('{"__widget__": 5') + + # this can be used with a TO_JSON method in some "widget" class + # for serialisation to json: + sub WidgetBase::TO_JSON { + my ($self) = @_; + + unless ($self->{id}) { + $self->{id} = ..get..some..id..; + $WIDGET{$self->{id}} = $self; + } + + { __widget__ => $self->{id} } + } + =item $json = $json->shrink ([$enable]) Perl usually over-allocates memory a bit when allocating space for