最近使ってるモジュールの話

Hokkaido.pm#9 - 2013/03/09 in 北海道
xaicron

自己紹介

免責

本日発表する内容は、個人的な考えや意見であり、
所属する組織、会社とは一切関係ありません。

免責

本日発表する内容は、個人的な考えや意見であり、
所属する組織、会社とは一切関係ありません。

また、スピリチュアルトークはできません。

というわけで

今日は、最近使ってるモジュールの話とかを中心にまったりやっていこうと思います。

いきなり本題に入る前に

自分がどんなふうに使うモジュールを選んでいるのか

CPAN モジュールの選定基準

2008年ごろ書かれたいい記事があります。

CPANソムリエになる方法

ざっくりまとめると

って感じですね。

俺基準

自分の基準としてはプラスして以下のようなところを見てる

俺基準 (1)

俺基準 (2)

俺基準 (3)

俺基準 (4)

俺基準 (5)

俺基準 (6)

ただし、全部ケースバイケースです!

モジュール選定のまとめ

ミニマルで、やりたいことがはっきりしてて遅くなさそうなモジュールを選ぶ

Any::Moose と Moose と Mouse について

Moo と Mouse の使い分け

閑話休題

というわけで本題。

自分が使ってるモジュールの紹介

実行中にモジュールを use したい

いろいろある

それぞれの特徴

最近

大体は Module::Runtime#use_module でいっかなーって思っているのでそれ使ってる。

Module::Runtime は実は Class::Load が内部的に使っていたりします。

HTTP リクエストしたい

いろいろある

それぞれの特徴

Furl について

最近また活発に開発されていたんですが、とりあえずまたある程度機能が揃ったので落ち着く予定です。

最近、以下の様な機能が追加されています。

Furl::Request が返るようになった

LWP とほぼおんなじ感じに使えます。

use strict;
use warnings;
use v5.16.2;
use Furl 2.10;

my $furl = Furl->new;
my $res = $furl->get('http://example.com/');

# リクエストした内容の Furl::Request オブジェクト
my $req = $res->request;

# HTTP::Request->dump
say $req->as_http_request->dump;

# HTTP::Response->dump
say $res->as_http_response->dump;

ちゃんとキャプチャしたい場合

capture_requset を有効にすると、Furl::Response から取得できる。

my $furl = Furl->new(
    capture_request => 1, # 実際に送った生 HTTP を保存
);

my $res = $furl->post(
    'http://localhost:5000/',
    [ 'X-Foo' => 1 ],
    [ foo => 'bar' ],
);
say $res->captured_req_headers . $res->captured_req_content;

DB に接続したい

いろいろある

それぞれのモジュールの特徴

DBIx::Handler と DBIx::Sunny を組み合わせる

以下のようにすると組み合わせて使えて捗る

use DBIx::Handler;

my $handler = DBIx::Handler->new($dsn, $user, $pass, {
    RootClass => 'DBIx::Sunny',
});
$handler->txn(sub {
    my $dbh = shift;
    ...
    $dbh->do(...); # SQL にコメントもつけてくれる
    # ここで勝手に commit してくれる
});

Q. O/R Mapper がありませんね?

A. すいません、使ってません...

クエリビルダー

いろいろある

それぞれの特徴

テンプレートエンジン

いろいろある

それぞれのモジュールの特徴

新規プロジェクトでは Text::Xsalte を使うと良い。
じぶんはコードジェネレーターとかでも使ってるけど、そのへんは T::MT でもよい。

スクレイピング

それぞれのモジュールの特徴

最近は、JavaScript 使えないと厳しいサイトが多いので Selenium::Remote::Driver + PhantomJS の組み合わせに期待

データをシリアライズしたい

いろいろある

それぞれのモジュールの特徴

日付処理をしたい

いろいろある

それぞれの特徴

日付処理の適当なベンチマーク

単純に、ISO8601 な形式の文字列を現在時刻から得るコードのベンチ

use strict;
use warnings;
use feature 'say';
use Config;
use Benchmark qw(cmpthese :hireswallclock);

use DateTime ();
use Time::Piece::ISO ();
use Time::Local ();
use POSIX ();

say "perl-$Config{version} ($Config{archname})";
say "DateTime    : $DateTime::VERSION";
say "Time::Piece : $Time::Piece::VERSION";
say "POSIX       : $POSIX::VERSION";

my $time = CORE::time;
say DateTime->from_epoch(epoch => $time)->iso8601;
say Time::Piece::gmtime($time)->datetime;
say POSIX::strftime('%Y-%m-%dT%H:%M:%S' => gmtime($time));

cmpthese -1 => {
    'DateTime' => sub {
        DateTime->from_epoch(epoch => $time)->iso8601;
    },
    'Time::Piece' => sub {
        Time::Piece::gmtime($time)->datetime;
    },
    'POSIX::strftime' => sub {
        POSIX::strftime('%Y-%m-%dT%H:%M:%S' => gmtime($time));
    },
}, 'all';

__END__
perl-5.16.2 (darwin-2level)
DateTime    : 1.01
Time::Piece : 1.20_01
POSIX       : 1.30
Benchmark: running DateTime, POSIX::strftime, Time::Piece for at least 1 CPU seconds...
  DateTime: 1.10119 wallclock secs ( 1.10 usr  0.01 sys +  0.00 cusr  0.00 csys =  1.11 CPU) @ 13837.84/s (n=15360)
POSIX::strftime: 1.08495 wallclock secs ( 1.08 usr  0.00 sys +  0.00 cusr  0.00 csys =  1.08 CPU) @ 217738.89/s (n=235158)
Time::Piece: 1.11906 wallclock secs ( 1.12 usr  0.01 sys +  0.00 cusr  0.00 csys =  1.13 CPU) @ 58553.98/s (n=66166)
                    Rate        DateTime     Time::Piece POSIX::strftime
DateTime         13838/s              --            -76%            -94%
Time::Piece      58554/s            323%              --            -73%
POSIX::strftime 217739/s           1474%            272%              --

だいたいこんな感じ。

モジュールのビルダー

いろいろある

それぞれの特徴

Module::Build::Pluggable::CPANfile の例

$ cat Build.PL

use strict;
use warnings;
use Module::Build::Pluggable qw(CPANfile);

my $build = Module::Build::Pluggable->new(
    license        => 'perl',
    dynamic_config => 0,

    configure_requires => {},
    build_requires     => {},
    requires           => {
        perl => '5.008001',
    },

    no_index    => { 'directory' => [ 'inc' ] },
    name        => 'Foo-Bar',
    module_name => 'Foo::Bar',

    # script_files => [''],

    test_files           => (-d '.git' || $ENV{RELEASE_TESTING}) ? 't/ xt/' : 't/',
    recursive_test_files => 1,

    meta_merge => {
        resources => {
            repository => 'https://github.com/xaicron/p5-Foo-Bar',
            bugtracker => 'https://github.com/xaicron/p5-Foo-Bar/issues',
        },
    },

    create_readme  => 1,
    create_license => 1,
);

$build->create_build_script();
$ cat cpanfile

# requires 'Foo::Bar' => '0.01';

on configure => sub {
    requires 'Module::Build'                      => '0.40';
    requires 'Module::Build::Pluggable::CPANfile' => '0.02';
};

on test => sub {
    requires 'Test::More'     => '0.98';
    requires 'Test::Requires' => '0.06';
};

on develop => sub {
    requires 'Test::Pretty'         => '0.22';
    requires 'Test::Name::FromLine' => '0.09';
};

ちなみに、いまあらたな toolchain がもりもりと作られているので乞うご期待

ファイル操作まわり

いろいろある

それぞれの特徴

並列処理したい

いろいろある

それぞれの特徴

Log を吐きたい

いろいろある

それぞれの特徴

メールを送りたい

Email::Send はもうメンテされていないので Email::Sender を使いましょう。

長らく Moose で遅かった Email::Sender は Moo になったので起動も高速になりました。
これでコマンドラインでも安心して使えますね!

Test モジュール

Perl テスティング ハンドブック があるじゃないですか!

例外処理

http://yappo.github.io/talks/20130329-perlcasual7-exception/#/title をご覧あれ!

まとめ

そういえば、むかし 今日のCPANモジュール というページがあってこれがすごい参考になってよく見てたのを思い出しました。

というわけで、最近みんながなんかこういうの使ってるよ的な話があんまりまとまってなかったので、そういう内容にしてみました。

それ CPANモジュールガイド で!という話もありますが、とりあえず今回は一度も開かずに、使ってる or 使おうと思っているものだけを紹介しました。

まぁ、なんというか好きなモジュール使えばいいんですけどね!

Fin.

j or →: next

k or ←: prev

h or ↑: list

l or ↓: return

o or ↵: open

? or /: toggle this help