JPA セミナー #1 (Session 1 Better Perl Practices 最新 Perl 開発手法のススメ)

自己紹介

ベストではなくベターを目指す

  • どれだけやっても不満は残るもの
  • 最初からうまくやらなくてもいい徐々に上を目指そう
  • 失敗したらよく考え次は成功させる

設計

  • ゴールをはっきりと
  • 背伸びはしないさせない

テスト

  • テストはゴールではない
  • テストではなく API を設計するところから
  • カバレッジ率に執着しない

リファクタリング

  • 避けられない運命
  • やるからには意義のあるものに
  • 失敗から学ぶ

つまりは API

  • 自分のためにシンプルに
  • 使いやすく分かり易く包括的な API を作り生産性をあげバグを減らす

大事なこと

習慣にするには

  • 大変だと思わせない
  • 正しいことはしやすく
  • 間違ったことはしづらく

テストの仕方

  • スキーマクラス
  • アプリケーション
    • Test::Class, Test::FITesque
    • ワークフローテスト

テスト

  • Test::Class
  • Email::Send::Test
  • Test::WWW::Mechanize

設計の仕方

  • まずは動くものを作る
  • 大まかな使い方を考える
  • ひとつひとつゴール(メソッド)を設定する

ユニークじゃなくても良い

  • 同じことをしようとした人は他にもいるはず
  • 似たような機能を探そう
  • Google で他のアルゴリズムを検索したり
  • テストも拝借できる CPAN モジュールがベター

何度も繰り返す

  • 煮つめてかさを減らす
  • それが「秘伝のタレ」になる
  • ソフトは液体、意志ではない
  • ユニットテストAPI のテストが済んだら後は組み立てるだけ
  • 雨だれ石をうがつ

Web != Desktop

  • 環境をコントロールできる
  • インストール先もコントロールできる
  • 遅い?スケーラビリティ!サーバーを追加

ベターアプリのために

ベター Perl

シンプルだけど

my $foo = $request->param->{foo};
my $bar = $request->param->{bar};

良いコードはタイプ数が少し増える

my $data = $request->params;
my $foo = $data->{foo};
my $bar = $data->{bar};

タイプしなければいいってものでもない

my $s = ($api ? $api->params : $request->params) || $request->params;
${"__PACKAGE__::$_"} = ($s->{$_}) for keys %$s;

コードの短さを競うゲームではない

use strict;
use warnings;

Test::Class

  • テストモジュールとしてはベスト
  • chromatic や Ovid もこれについて書いている http://modenperlbooks.com/

Test::Class の理由

  • パッケージベース
  • Test::名前空間 にテストコードをまとめられる
  • .t ファイルより柔軟に書ける(コードの再利用)
  • テストの設定もし易くなる

ベースクラスを利用する

  • 共通の機能をまとめる
  • 変更もかんたん
  • Perl のいいところ(多重継承をサポート)
  • それぞれのクラスでどこが同じでどこが違うか考え構築する

少ない手数でより多くのことを

  • コードをより良く
  • 手数は少なく
  • その後は use Moose

必要なものを使う

  • CPAN にはオブジェクト指向API モジュールがありすぎ
  • Moose はそれらの機能の大部分をカバーしている
  • そこまで必要なければ use Mouse で

Moose でハードコードを減らす

  • 考えられる全てを設定可能に
  • やり方はすぐに分かるようになる
  • やればやるほど楽になる
  • MooseX::SimpleConfig

お気に入り

with 'MooseX::SimpleConfig';
with 'MooseX::Getopt';
has +configfile => (
    default =>
        (
         grep { defined $_ and -f $_ } @places_to_loook
        )[0] || ""
);

複数パスから設定ファイルを抽出し、その中からオブジェクトに has() などで指定した要素を初期化してくれる

まとめ

  • 書くコードを減らす(ベースクラス)
  • 大事なところはテストする
  • Moose(書くコードを減らす)
    • 設定で動作変更可能に

Class::MOP

Moose = ベター API

  • まともなアクセッサー
  • 初期化コードの遅延評価
  • コードは少なく
  • テストは多く

自家製ではない

  • 自分で書くより Moose を使う方が良い
    • 多くの人の手が入っている
    • 膨大な量のテストがある
  • Moose を使えば出来ることが広がる

遅い?

  • Moose は別に遅くない
  • 他のモジュールと比べて遅いだけ
  • しかもほとんどは起動時の問題
    • 線形スケーラビリティ(かかる時間は一定)
    • 遅いと思ったらハードウェアを追加

少しずつ拡張していけば良い

すぐに使いたいなら

  • 型チェック
  • 'ArrayRef[MyObject]' なんてことも可能

注意

  • そのうちなんでもロールに見えてくるようになる
  • それが普通
  • でも誘惑にまけないように
  • それでも必要だと思ったらロールに