Perl Advent Calendar 2014の7日目の記事です. 宜しくお願いします.
さて, 昨日の記事は@FromAtomさんの「Perlのprintデバッグをシュッと見やすくする」でした.
printデバッグはデバッグの中でも基礎中の基礎, とりあえず詰まったらprintデバッグで試してみる... という方は結構多いのではないでしょうか.
昨日の記事ではData::Dumperを紹介されていましたが, デバッグに役立つダンプ用のモジュールは他にもあります.
今日はその中の1つ, Data::Printerを紹介したいと思います.
Data::Printerのインストール
cpanm
コマンドが使えれば簡単です.
$ cpanm Data::Printer
ここがData::Dumperと比べた時のData::Printerの弱点です. つまり「便利だけど, コアモジュールじゃない」という所.
「どんな環境でも使える」という取り回しの良さ(?)は, コアモジュールのData::Dumperが非常に有利です.
というわけで, 時と場合に応じて, DumperとPrinterを使い分けることが大切になってくる訳です.
Data::Dumperの使い方
my $data = { abc => 1, def => 2, array => [ 1..3 ], hash => { a => 1, b => 2, c => 3, }, coderef => sub { print "hello!" }, };
このようなデータ構造を, Data::DumperとData::Printerで表示してみます. コードはこんな感じ.
use Data::Dumper; use DDP; my $data = { abc => 1, def => 2, array => [ 1..3 ], hash => { a => 1, b => 2, c => 3, }, coderef => sub { print "hello!" }, }; print Dumper $data; # Data::Dumperで表示 p $data; # Data::Printerで表示
DDP
というのは, Data::Printerのエイリアスのようなものと思って下さい.
use DDP;
とすると, Data::Printerの機能が使えるようになります.
上のコードのように, p
という関数が使えるようになるので, これにダンプしたいデータ構造を与えればOKです.
さて, このコードを実行すると, 次のように表示されます.
# Data::Dumperの表示
$VAR1 = {
'abc' => 1,
'coderef' => sub { "DUMMY" },
'hash' => {
'b' => 2,
'a' => 1,
'c' => 3
},
'array' => [
1,
2,
3
],
'def' => 2
};
# Data::Printerの表示
\ {
abc 1,
array [
[0] 1,
[1] 2,
[2] 3
],
coderef sub { ... },
def 2,
hash {
a 1,
b 2,
c 3
}
}
スクリーンショットを見て頂くと, Data::Printerを使った場合, 出力がカラフルになっているのがわかると思います.
Data::Perinterの出力は, Data::Dumperの出力よりもシンプルで見やすいと思っています.
サブルーチンリファレンスの出力
さて, Data::DumperもData::Printerも, $data->{coderef}
に格納されているサブルーチンリファレンスが正しく出力されていないことがわかります.
'coderef' => sub { "DUMMY" }, # Data::Dumperの場合
coderef sub { ... }, # Data::Printerの場合
Data::Printerでは, DDP
をuse
する時に, use DDP { deparse => 1 };
のようにuse
をすれば, サブルーチンリファレンスの中身(実際のコード)出力してくれるようになります.
use DDP { deparse => 1 }; my $data = { coderef => sub { print "hello!" }, }; p $data;
このコードを実行すると, 次のように出力されます.
\ {
coderef sub {
print 'hello!';
}
}
日本語のダンプ
use Data::Dumper; use DDP { deparse => 1 }; my $data = { en => 'hello!', ja => 'こんにちは!', }; print Dumper $data; p $data;
次は, このように日本語を含んだデータをダンプしてみます.
$VAR1 = {
'ja' => "\x{3053}\x{3093}\x{306b}\x{3061}\x{306f}!",
'en' => 'hello!'
};
\ {
en "hello!",
ja "こんにちは!"
}
Data::Printerであれば, このようにそのままの日本語で出力してくれます.
ちなみにData::Dumperで日本語文字列を日本語で出力したい場合, @bayashiさんのData::Dumper::AutoEncodeを利用する, などの選択肢が出てくると思います.
Data::Printerを楽に使う
自分の場合, VimのPerl用スニペットファイルに次のような設定を入れています.
snippet dd
use DDP { deparse => 1 };
snippet dw
use DDP { deparse => 1 };
p
Data::Printerでデバッグしたいと思った時は, このスニペットからData::Printer用のコードを展開して使っています.
まとめ
Data::DumperやData::Printerといったダンプしてくれるモジュールはprintデバッグの友, いざという時に使いこなせるようにしておきたいですね.
ちなみに, 今回紹介したもの以外のPerlのダンパー系モジュールのまとめについては, @hirobanexさんのこちらの記事が参考になります.
さて, 明日のPerl Advent Calendar 2014は... 今のところ担当者不在ですね. 果たして誰が記事を書くのか!? 非常に楽しみです.