― Web Technology and Life ―

Perlのデータ構造をダンプするためのモジュール群

2013-09-29
マコピー(@mackee_w)にDDPって教えてもらったので、この機会にみんなに大人気のCPANモジュールまとめ記事を書くよ!!とりあえず、みんな大好きなまとめ記事なんで、はてぶをポチっとしてね!!

今回紹介するモジュール群

結論的には、DDPがいいよって話ですが、よく知らない方は以下を読んでいただくととても楽しいと思います。

Data::Dumper

みんな大好き定番モジュールですね!!これがないと死んじゃうって近藤先生がおっしゃっていた気がします。

以下のように使います。

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;

my $data = +{
    hash => +{
        aaa => 111,
        bbb => 222,
        ccc => 'ほげほげ',
    },
    code => sub {
        warn "ほげほげ";
    },
};

use Data::Dumper;
warn Dumper $data;

ただ、デフォルトの設定だと問題がって、上記のコードの出力結果が以下のようになります。

$VAR1 = {
          'code' => sub { "DUMMY" },
          'hash' => {
                      'ccc' => "\x{307b}\x{3052}\x{307b}\x{3052}",
                      'aaa' => 111,
                      'bbb' => 222
                    }
        };

Data::Dumperの基本設定の問題

ネストがうざいっているのもあるんですが、クリティカルなのが以下の二点ですね

  • Perlの内部(utf8フラグ付き)文字列が読めない記号になっている
  • コードリファレンスが表示されない

Data::Dumper::AutoEncode ~Perlの内部文字列をちゃんと日本語にしてくれる~

そこで登場するのがbayashiさん作のこのモジュールです。

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;

my $data = +{
    hash => +{
        aaa => 111,
        bbb => 222,
        ccc => 'ほげほげ',
    },
    code => sub {
        warn "ほげほげ";
    },
};

use Data::Dumper::AutoEncode;
warn eDumper $data;

このように書いて出力すると

$VAR1 = {
          'code' => sub { "DUMMY" },
          'hash' => {
                      'bbb' => '222',
                      'aaa' => '111',
                      'ccc' => 'ほげほげ'
                    }
        };

見事に日本語が読めますね!!!

しかし、コードリファレンスが読めないのが苦しいところです。。。

Data::Dumper::Concise ~コードリファレンスを表示してくれる~

そこで登場するのがこのConciseです。

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;

my $data = +{
    hash => +{
        aaa => 111,
        bbb => 222,
        ccc => 'ほげほげ',
    },
    code => sub {
        warn "ほげほげ";
    },
};

use Data::Dumper::Concise;
warn Dumper $data;

このように書いて、出力すると

Wide character in warn at hogehoge.pl line 19.
{
  code => sub {
      use warnings;
      use strict;
      warn 'ほげほげ';
  },
  hash => {
    aaa => 111,
    bbb => 222,
    ccc => "\x{307b}\x{3052}\x{307b}\x{3052}"
  }
}

コードリファレンスが出力されて素晴らしいですね!!!

ただ、片手落ちで、今後はPerlの内部文字列が変な記号のままになってしまいました。。。

Data::Printer ~フルスタックDumpツール~

Data::Dumper::AutoEncodeにしてもData::Dumper::Conciseにしても片手落ちなので、なんか両方満たす最強モジュールないかなーって思っていると、待ってましたとばかりに登場するのがData::Printerです。

ドキュメントをみるとわかるのですが、もりもりできっとなんでもできるんだろうなって思うくらいモリモリです。

ただ、モリモリ過ぎてドキュメント読むの大変ですよね。。。。

DDP ~シンプルなData::Printerラッパー~

Data::Printerがヘビーするぎるので、同じAuthorがシンプルないい感じのラッパーを作っていました。

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;

my $data = +{
    hash => +{
        aaa => 111,
        bbb => 222,
        ccc => 'ほげほげ',
    },
    code => sub {
        warn "ほげほげ";
    },
};


use DDP {deparse => 1,};
p $data;

このように、deparseオプション付でuseすることで、CodeRefも出力できます。

[hirobanex@000-local-env]$ perl hogehoge.pl                                                                                    
Wide character in print at /home/hirobanex/.plenv/versions/5.18.0/lib/perl5/site_perl/5.18.0/Data/Printer.pm line 190.
\ {
    code   sub {
            use warnings;
            use strict;
            warn 'ほげほげ';
        },
    hash   {
        aaa   111,
        bbb   222,
        ccc   "ほげほげ"
    }
}

素晴らしいですね!!

オブジェクトをDumpしたとき

後述するようにこのモジュールはマコピーさんに教えてもらったんですが、「オブジェクトをDumpしたときもカッコイイぜ!」って教えてもらったので合わせて紹介しておきます。

サンプルコード

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Furl;

my $furl = Furl->new();

use DDP;
p $furl;

use Data::Dumper;
warn Dumper $furl;

出力結果

Furl  {
    public methods (9) : agent, delete, env_proxy, get, head, new, post, put, request
    private methods (0)
    internals: Furl::HTTP
}
$VAR1 = bless( do{\(my $o = bless( {
                          'capture_request' => 0,
                          'inet_aton' => sub { "DUMMY" },
                          'no_proxy' => '',
                          'timeout' => 10,
                          'ssl_opts' => {},
                          'proxy' => '',
                          'header_format' => 1,
                          'max_redirects' => 7,
                          'connection_header' => 'keep-alive',
                          'stop_if' => sub { "DUMMY" },
                          'bufsize' => 10240,
                          'headers' => [
                                         'User-Agent',
                                         'Furl::HTTP/2.16'
                                       ],
                          'connection_pool' => bless( [
                                                        ''
                                                      ], 'Furl::ConnectionCache' )
                        }, 'Furl::HTTP' ))}, 'Furl' );

Data::Dumperと比較すると、どんなメソッドがあるかどうかとかわかったりするので、なかなか見やすいですね!!

紹介したモジュールのまとめ

というわけで、まとめめると以下のようになります。

モジュール名 日本語文字列の表示 CodeRefの表示 見やすい整形
Data::Dumper
Data::Dumper::AutoEncode
Data::Dumper::Concise
Data::Printer
DDP

△もりもりで見づらくなっていますが、一応公平を期してオプションやちょっとしたハックで可能なことは△にした次第です。一応、ほとんどData::Dumperのラッパー的な感じなんで、Data::Dumperと同じオプション追加すれば、いい感じになったりしますが、オプションって思い出したり調べたりするのだるいので、DDPが一番オプション少なくて行けるしいいと思います。

というわけで、結論的には、DDPは最初からいい感じだし、DDPがいいんじゃないかなーと思う次第ですね。

終わりに ~モヒカンのマコピー最高!!~

もともと、Perl Beginners#10っていう初心者向けPerl勉強会でExcel出力のCSV取込みから学ぶ4つのCPANモジュールってLTしていたら、モヒカンのマコピーが「なんで、DDP使わないんですか?」ってニュアンスの内容をLTの途中に小飼弾さん風に突っ込んできて、「モヒカンまじこえー!!!」って思ったんですが、おとなしく調べてHachioji.pm#32で今回記事にした内容をLTでやったっていう裏話ですね。

やっぱりモヒカンのマコピー++!!

Perl hachioji.pm update_at : 2013-09-29T19:14:21
hirobanex.netの更新情報の取得
 RSSリーダーで購読する   
blog comments powered by Disqus