■2008-02-16
* [Perl][メモ] 再度JSON周り
前回、XSにバグがあるかなあと思って作者のMarcさんとやりとりしましたが、結局、問題ないということを確認しました。私の早とちりでした。すいません。UTF8フラグが立っても影響でないですね。
XSとPPの動作の違いはPP側に問題があったためで、最新バージョンでは修正してあります。自分の把握している限りでは完全にXSと同じ出力になっているはずです(エラーメッセージも一部を除いて一緒)。
あと、JSON::XS::VersionOneAndTwoというのが出たようなので、ちょっと余計な話を。
JSON::XSはメジャーバージョンアップの際、エクスポートされる関数名がto_json, from_jsonからencode_json, decode_jsonに変わりました。この関数はJSON::XS->new->utf8->encode/decode
相当(実際はそれより高速)なのですが、utf8以外のオプションを設定できません。なので、旧objToJsonのようにJSON側でオプションを渡せる関数として当初はen/decode_jsonをあてようとしたのですが、そちらの名前の方がutf8がらみであることが明確(decode, encode)になるので、名前を変更しよう、ということになりました。その代わりに、JSON側はto_json, from_jsonでオプションを設定できるようになった次第。
* [Perl][メモ] use JSON -convert_blessed_universally
JSON 1.xの$JSON::CnovBlessedの代わりにas_nonblessedオプションがあるのですが、バックエンドがXSの場合はuse JSON -support_pp_by
しなければならないので嬉しくない代物です。メソッド名も気に入らない(できればconvert_blessedがよい)。
ところで実際のconvert_blessedオプションは、encodeに渡したblessされたオブジェクトがTO_JSONメソッドを持っているとそのメソッドを呼び出してくれます。なので、下記のコードのようにUNIVERSAL::TO_JSONを定義すればas_nonblessedの代わりになるなあと。バージョン2.07からuse JSON -convert_blessed_universally
でセットされます。XSの作者がconvert_blessedの動作は将来変更するかもといっているので、これも実験的な機能になります……
*UNIVERSAL::TO_JSON = sub { my $b_obj = B::svref_2object( $_[0] ); return $b_obj->isa('B::HV') ? { %{ $_[0] } } : $b_obj->isa('B::AV') ? [ @{ $_[0] } ] : undef ; }