Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PerlとJSON / Perl and JSON

120b74af626c2b23f954926ef68ac5d6?s=47 papix
May 24, 2019

PerlとJSON / Perl and JSON

120b74af626c2b23f954926ef68ac5d6?s=128

papix

May 24, 2019
Tweet

Transcript

  1. PerlとJSON id:papix (@__papix__) 株式会社はてな

  2. papix 株式会社はてな アプリケーションエンジニア (2017年2月~) シニアエンジニア (2019年2月~) ブログMediaチーム サービスリード兼スクラムマスター 「はてなブログ」をつくっています アカウント類

    はてな: id:papix Twitter: @__papix__ GitHub: papix / CPAN: PAPIX ブログ: https://papix.hatena(blog.(com|jp)|diary.jp)/ 趣味はPerlと, (交通機関を利用した)旅行 JGC修行は完遂済み, 今年はSFC修行をしています
  3. JSON JavaScript Object Notation JavaScript Object Notation (JSON 、ジェイソン)は軽量な データ記述言語の1

    つである。構文はJavaScript におけるオブジ ェクトの表記法をベースとしているが、JSON はJavaScript 専用の データ形式では決してなく、様々なソフトウェアやプログラミング 言語間におけるデータの受け渡しに使えるよう設計されている。 by Wikipedia Perlでも, JSONを扱うライブラリが用意されている
  4. Perl界の(代表的な)3つのJSON JSON::PP JSON::XS JSON

  5. JSON::PP PP(Pure Perl)実装のJSONモジュール v5.13.9よりコアモジュール perl コマンド単体で動かしたいスクリプトならJSON::PPを 使っておくと良い

  6. JSON::XS XSを使ったJSONの実装 XSを使って, C言語のコードやライブラリとPerlを繋いで実装 しているので(Pure Perlよりも)高速 cpanfile などに書いていて, JSON::XSがある環境なら明示的に JSON::XSを使えばよい

    コアモジュールではない
  7. JSON JSON::XSがあればそれを, なければJSON::PPを使ってくれる モジュールなどで, よしなに使わけて欲しい時はJSONを使って おけばよい コアモジュールではない

  8. まだまだあるJSONファミリー Cpanel::JSON::XS Cpanelという会社が実装した, XSを使ったJSON JSON::MaybeXS Cpanel::JSON::XSとJSON::XSとJSON::PPをよしなに使って くれる

  9. JSONことはじめ JSON::XSを例に, Perlで実際にJSONを扱う例を紹介していきます

  10. PerlのHash/ArrayリファレンスをJSONにする use JSON::XS qw(encode_json); my $json = encode_json({ a =>

    1, b => 2 }); print $json; # => {"a":1,"b":2}
  11. JSONをPerlのデータ構造にする use JSON::XS qw(decode_json); use Data::Dumper; my $ref = decode_json('{"a":1,"b":2}');

    print Dumper $ref; # $VAR1 = { # 'a' => 1, # 'b' => 2 # };
  12. ちなみに... decode_json は, JSON::XS->new->utf8->decode と同じ encode_json は, JSON::XS->new->utf8->encode と同じ use

    JSON::XS; my $json = JSON::XS->new->utf8->encode( { a => 1, b => 2, c => 3 } );
  13. こういう時はどうする?

  14. JSONにする時, Hash Randomizationを回避したい Perl 5.18以降, Hash Randomizationが導入された PerlのHash/ArrayリファレンスをJSONにするとき, キーの順序 が不順になることがある

    use JSON::XS qw(encode_json); my $json = encode_json({ a => 1, b => 2, c => 3 }); print "$json\n"; $ perl json.pl {"c":3,"a":1,"b":2} $ perl json.pl {"a":1,"c":3,"b":2} $ perl json.pl {"b":2,"c":3,"a":1}
  15. JSONにする時, Hash Randomizationを回避したい 解決策としては, Canonicalモードを使う キーをソートした上でJSONにしてくれる use JSON::XS; my $json

    = JSON::XS->new->utf8->canonical->encode( { a => 1, b => 2, c => 3 } ); print "$json\n"; # {"a":1,"b":2,"c":3}
  16. JSONにするとき, オブジェクトが含まれていても無視したい PerlのHash/ArrayリファレンスをJSONにするとき, 通常オブジェク トが含まれると例外になる encountered object 'Obj=HASH(0x7ff069003418)', but neither

    allow_blessed, convert_blessed nor allow_tags settings are enabled (or TO_JSON/FREEZE method missing) use JSON::XS qw(encode_json); my $hash = { a => 1, b => Obj->new, }; my $json = encode_json($hash); # XXX
  17. JSONにするとき, オブジェクトが含まれていても無視したい allow_blessed をOnにすると, オブジェクトは無視して null に してくれる use JSON::XS

    qw(encode_json); my $hash = { a => 1, b => Obj->new, }; my $json = JSON::XS->new->utf8->allow_blessed->encode( $hash ); print $json; # => {"a":1,"b":null}
  18. JSONにするとき, オブジェクトもよしなにJSONにしたい オブジェクト側に TO_JSON メソッドを用意しておけば, オブジェク トの TO_JSON の返り値でJSONを作ってくれる use

    JSON::XS; my $hash = { a => 'b', c => Obj->new, }; my $json = encode_json($hash); print $json; # => {"a":"b","c":{"cc":11}} package Obj; sub new { bless {}, $_[0] } sub TO_JSON { {cc => 11} }
  19. JSONにするとき, 型を明示したい JSON::Typesを使いましょう use JSON::XS; use JSON::Types; my $hash =

    { number => JSON::Types::number 1, string => JSON::Types::string 1, bool => JSON::Types::bool 1, }; my $json = encode_json($hash); print $json; # {"number":1,"string":"1","bool":true}
  20. JSON::Types 実装は素朴 sub number($) { return undef unless defined $_[0];

    $_[0] + 0; } sub string($) { return undef unless defined $_[0]; $_[0] . ''; } sub bool($) { $_[0] ? \1 : \0; }
  21. ちなみに... booleanについては, (Perlに存在しない概念なので)decodeするとき にどうなるかはライブラリごとに決まっている 例えば, JSON::XSなら, true は $Types::Serialiser::true に,

    false は $Types::Serialiser::false にデコードされる 更に, boolean_values を使って, JSONの true / false をデ コードするときの値を上書きすることができる
  22. まとめ PerlにはJSONを扱うための道具がいろいろある そしてJSONをよしなに扱うテクニックがいろいろある PerlとJSONとうまくつきあっていきましょう