この記事はPerl 5 Advent Calendar 2015の一貫として「先走って」書いております。
ただいま、絶賛「IVS CTO Night&Day 2015 Fall」というイベントに来ていて100名ほどのスタートアップやベンチャーのCTOさん達に囲まれています。そのイベントの事前のアンケートには「社内での主力言語はなんですか?」みたいな質問がありました。さて結果発表を画像で貼り付けますと...
ちょっと見えにくいかもしれませんが「Rubyが27 PHPが20」を占める中「Perlが1」という結果です。僕Perlって書いたので「Perl主力なところってうちだけ」ですねw
まぁといってもちょっとそれは過小評価な表現で、はてなさんがScalaとPerlをどちらも主力と考えていたり「アンケートに答えなかった」というガイアックスさんもPerl企業です。このイベントに参加していない企業さんでも、Perlを使っている実力のある社名がぱっと浮かびます。ただ!そもそもアンケートの選択肢にPerlがなかったので「その他自由欄」に記載しなくてはいけなかったり、写真にある通りスライド上に「Perl 1」とあるのはちょっと寂しいのです...
前置きが長くなってきましたが「Perlぜんぜんイケてるやん」って思うし、アンケートに回答した通りBoketeのバックエンド及びフロントのWebサイトはほぼ100%Perlで書かれています。Perlが担当するアプリケーションレイヤーはすごく安定稼働です。ってことでPerlでWebサービスをつくる際に必須なCPANモジュールの中から、主にBoketeで使っているものを20個ほどピックアップしてみます。元々Perlを使っている方にとっては当たり前なモジュールかもしれませんが他言語を使ってる方が「Perlもライブラリ揃ってるやん」って思ってくれるとこれ幸いです。
ではいってみましょー
基本モジュール
1. Mouse
Perlでも素でOOPは出来るのですが、具体的なアプリケーションレベルだとこのMouseを使ってクラスをつくってます。継承、Roleの概念もあります。面白い機能の一つにlazy_build
があります。これはアクセッサを定義する際にlazy_build
を指定すると「初めて呼ばれた際に」デフォルトの値をセットしてくれるというものです。
use Mouse; use LWP::UserAgent; has ua => ( is => 'ro', isa => 'LWP::UserAgent', lazy_build => 1 ); sub _build_ua { return LWP::UserAgent->new(); } sub get_content { my ($self, $args) = @_; my $url = $args->{url}; my $res = $self->ua->get($url); return $res->content; }
Mouseの他にも元ネタだったり派生したものとしてMooseやMooもありますので、これらを使えばOOPは快適です。
2. Data::Validator
メソッドの引数の型を含む「チェック」に使っています。上記のコード例にあるget_content
をより厳密にしたい!なんて時はこんな感じで使います。
use Data::Validator; ...; sub get_content { state $rule = Data::Validator->new( url => { isa => 'Str', default => 'http://yusuke.be/', optional => 0 } )->with('Method'); my ($self, $args) = $rule->validate(@_); my $url = $args->{url}; my $res = $self->ua->get($url); return $res->content; }
3. Try::Tiny
モダーンにエラーハンドリングを書けます。
try { die "dying message..."; } catch { warn "Error: $_"; };
4. Path::Tiny
モダーンにローカルファイルのパス解決をしてくれます。それに加えて、ファイルの内容を舐めるslurp
や書き出すためのspew
などもあります。
use Path::Tiny; my $file = path('foo.txt'); my $text = $file->slurp(); print $text;
Webのバックエンド
5. Mojolicious
Perlにももちろん様々なWebフレームワークがありますが、サクッとつくったりある程度の規模かつViewまで担当するって時にはこのMojoliciousを僕は使ってます。 Perlには珍しくアグレッシブに後方互換を切り捨てるという開発方針があったりするのですが、まぁそれは置いといて、このフレームワークはRubyで言うSinatraとRailsの中間みたいな感じですごく使いやすいです。
言語違うけどMojoliciousはSinatraとRailsの中間でかつ、DSL臭が少ないので好きなんです
— Yusuke Wada (@yusukebe) 2015, 12月 4
6. Plack
フレームワークを使う分には触ることはないのですが、より特化したケースやパフォーマンスを重視したい際にはPSGIの実装であるPlackを素で使います。RubyにおけるRackの立ち位置なのですが、Perlの場合だとこれから紹介するいくつかのモジュールと組み合わせることによって実用的なアプリをつくりやすいです。
7. Router::Boom
例えばですが「このパスにアクセスが来たらこうする」というディスパッチャとしてRooter::BoomをPlackなどと組み合わせています。パス/entry/100
に来たリクエストをコントローラEntry
のshow
というメソッドで処理するなんて場合はこんなコードで再現出来ます。
use Router::Boom; my $router = Router::Boom->new(); $router->add( '/entry/{entry_id:[0-9]+}', { controller => 'Entry', method => 'show' } ); my $dest = $router->match('/entry/100'); # => {controller => 'Entry', method => 'show', entry_id => '100' }
8. JSON::RPC
BoketeではWeb APIのフォーマットとしてJSONRPC
を採用しているので使っています。アプリ内では継承して若干改造しているのですが、まぁ問題なしで使えております。
9. OAuth::Lite2
これもBoketeアプリの認証認可という点でサーバ側及びクライアント側でも利用させてもらってます。他にもOAuthの実装はあるのですが、作者が日本人の方でよく熟考して実装されている、かつ、実装もシンプルなのでオススメです。というか今回紹介しているモジュールの多くは日本人の方がメンテしてくれているので「困った時に聴ける」「開発意図が分かる」ので良いです。
10. Starlet
PSGI対応のハイパフォーマンスWebアプリケーションサーバーです。なので上記したMojoliciousやPlackで実装したアプリケーションを本番環境で動かす際に必要となります。他にも、Starman、GazelleなどPSGIに対応したサーバーソフトがあるので用途に応じて使わけるといいでしょう。Server::StarterとあわせるといわゆるGraceful Restart
も出来るし、運用上Appサーバーレベルで異常が起きたことがほぼ無いので安心感あります。
Webアプリに便利
11. FormValidator::Lite
Webフォームの値を検証することに特化したライブラリです。なのでバリデーションをコントローラ層でもモデルでもどこでも自分が好きなところでやっちゃっうことが出来るでしょう。ベーシックにコントローラ部分でやる例としてMojoliciousをつかった例はこのようになります。
use Mojolicious::Lite; use FormValidator::Lite; FormValidator::Lite->load_constraints(qw/Japanese/); post '/' => { my $c = shift; my $validator = FormValidator::Lite->new($c->req); my $res = $validator->check( name => [qw/NOT_NULL/], name_kana => [qw/NOT_NULL KATAKANA/], {mails => [qw/mail1 mail2/]} => ['DUPLICATION'], ); if ($validator->has_error) { return $c->render( text => 'Not valid!' ); } $c->render( text => 'Valid!' ); }; app->start;
12. HTML::FillInForm::Lite
テンプレートなどを使って描画するHTMフォームの個々の要素のそれぞれに値を充填することが出来ます。ようは「戻るボタン押したら入力したのが全部消えてる><」問題が解決出来ます。
13. HTML::Scrubber
MojoliciousのテンプレートMojo::Template
をはじめ、テンプレートエンジンには大抵HTMLエスケープ処理を容易にする、もしくは、デフォルトでエスケープされる機能がついています。が、場合によっては生HTMLをデータで持っていて、script
タグ等除去してそのまま描画したい、なんてことがあります。その際にこのHTML::ScrubberでタグをWhite or Black List形式で指定してセーフティにしています。
DB操作
14. Teng
ガッツリしたO/R MapperもあるんですがTengは厳密にはO/R Mapperとも言えないんじゃないか!ってほど簡素なDB操作をするためのモジュール。なので勝手にJOIN
が走るなんてことがないです。インターフェースもシンプルで直感的なのが好きですね。
my $iter = $db->search( 'entry', { category => 'podcast' }, { order_by => { id => 'desc' } } ); while(my $entry = $iter->next) { say $entry->title(); }
15. SQL::Maker
Tengは生SQLも受け付けるので、複雑なクエリを発行したい場合や条件で分岐したい時などはこのSQL::MakerでクエリをつくってからTengに渡すなんてことをしています。ようはこれ書きやすいクエリビルダーです。実はTengの内部でも利用されています。
その他
16. Imager
画像を扱う場合はGDやImageMagickのラッパーが存在するのでそれを叩けばいいのですが、このImagerの方がAPIがPerlishで使用感が良いです。
デバグとテスト
17. Devel::KYTProf
データベースやmemcachdへのクエリやHTTPのリクエスト状況などを開発しながら見ていくことは非常に重要です。その際にコード内で use Devel::KYTProf
するだけで標準出力に
0.228 ms [Cache::Memcached::Fast] get dbs:54e98de3b9aed9064e1834e0d6ac3a636a981f9f | Bokete::DB::Row::Boke:48
とかでちゃうの素敵です。
18. Test::mysqld
MySQLをバックエンドに持つアプリケーションをテストする際に便利すぎる。テストを走らせている間だけテンポラリーなmysqld
が立ち上がります。
19. Harriet
大抵prove
というコマンドで複数ファイルにわかれたテストをまとめて実行するのですが、Test::mysqldをprove中に使いまわしたりってのに使ってます。BoketeではMySQLだけではなく、MemcachedとRedisをテストの際、こいつで立ち上げてたりします。
20. Test::JSON::RPC::Autodoc
手前味噌で恐縮ですが、JSONRPC
を喋るPlackアプリケーションに対してテストを簡便に記載できるだけじゃなくて、APIドキュメントもMarkdown形式で書きだしてくれるモジュールです。Ruby実装のautodocをモチベーションにしてつくりました。Boketeではこれを使って吐き出したMarkdownをGitHub上で見てもらうことで仕様の共有をしています。
まとめ
以上、実践で使用しているモジュール群から「特徴的で」かつ「これがなきゃ困るぜ!」というライブラリを20個紹介しました。Perlはグルー言語とも呼ばれこうしたCPANモジュールを組み合わせて自分達なりにアプリケーションをつくっていけるので、非常に楽しい側面があります。それぞれドキュメントへのリンクを張っているので興味があれば見てみて下され!
Perlはじめる時にオススメの2冊
- 作者: Randal L. Schwartz,brian d foy,Tom Phoenix,近藤嘉雪
- 出版社/メーカー: オライリージャパン
- 発売日: 2012/07/25
- メディア: 大型本
- 購入: 7人 クリック: 22回
- この商品を含むブログ (17件) を見る
- 作者: Randal L. Schwartz,brian d foy,Tom Phoenix,伊藤直也,長尾高弘
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/08/21
- メディア: 大型本
- この商品を含むブログ (2件) を見る