Hatena::Groupcside

Cside::StudyMemo このページをアンテナに追加 RSSフィード

メインブログに書くまでもない自分用メモを垂れ流す。日々是勉強也。

カテゴリー
|

2012-10-21

[]t/foo/foo.tのように階層のあるテストはmake testの対象外

デフォルトは(t|xt)/*.tのみが対象。階層のあるテストを含めたいときはMakefike.PLでtests_recursive(Module::Installの関数)を呼ぶ必要がある

CPANモジュールガイドで知ったんだけどだいぶびっくりした。

あとこれも本に書いてあったんだけど、M::IのAPIは https://metacpan.org/module/Module::Install::API に載ってて、まずはここから入ればよい、とのこと。

2012-10-17

[]警告が出ないことをテストする

https://metacpan.org/module/Test::Warn

warning_is    {add(2,2)} undef, "No warnings for calc 2+2"; # or
warnings_are  {add(2,2)} [],    "No warnings for calc 2+2"; # what reads better :-)

[]インタラクティブシェル研究会

あとで書く

  • P::M::D::InteractiveDebuggerためす
  • Devel::REPL

2012-10-14

[]PerlでRSpecでいうwith()をやる

Test::Mock::Recorder というのを初めて知った。

あと最近たまたまno titleというモジュールも知った。これでもできるっぽい。

[]HTTP通信のTesting Modules

module やってくれること
Test::Fake::HTTPDフェイクサーバを立てる
Test::Mock::LWP::Conditional リクエストのstub

T::Mock::LWP とか T::Mock::Dispatch とかもあるけど、T::Mock::LWP::Coditional は以下の事情から作られたもの。

なぜかモジュールの名前に "モック" が入っているわけですが、これは既存の同様なモジュールに Test::Mock::LWP や Test::Mock::LWP::Dispatch というのがあるからだったりします。これらのプロダクトは、使い勝手に少々微妙なところがあったり、実際には依存していないのに requires 'Moose' していたりということがあって、今回置き換えとなるようなモジュールを書いてみました。

HTTP通信を含むモジュールのテスト #2 - Perl Advent Calendar Japan 2011 Test Track

[]テスト結果をフォーマットする

TAP::Formatter::* がTAPの出力を整形するモジュール群らしい。

no title


Masaki Nakagawa - 他言語から見たPerlのテスト - YouTube 見てて知った。

2012-10-04

[]require() は一度読み込んだモジュールについては、2度目は読みこまない。

require() ってエラー処理が親切になっただけの do() と思ってたけど、他にも違いがあるようだ。

一度読み込んだモジュールについては、2度目は読みこまない。

  • Perlのライブラリのパスからモジュールを検索する。
  • モジュール名の指定だけでモジュールの読み込みができる。
  • この2つがdoと比較した場合の、requireの利点です。

ttp://d.hatena.ne.jp/perlcodesample/20090208/1232890021

一度読み込んだモジュールについては、2度目は読みこまないの知らなかった。というか知らずにはまった。

2012-09-24

[]Roleの難しさ

RoleクラスをMock化する方法がわからないので継承にしてしまう罠。

Roleだと

package MyApp::Logger;
use Moose;

sub log { ... }

no Moose;
1;
package MyApp::Main;
use Moose;
with 'MyApp::Logger';

no Moose;
1;

みたいなとき、Loggerをモック化できない(やり方あるのかもしれないけど、、)から、Loggerと切り離して MyApp::Main 単体のテストをすることが出来ない。

なので結局Role使わず継承にして、親クラスをモック化して子クラスをテストする、という方法を最近は選択した。

Role使ったほうがMo[ou]seなら綺麗な設計になること多いし、これさえなければ使いたいんだけどね。。

[]それ List::MoreUtils::any じゃなくてハッシュでいいよね

今でもたまにやるのでメモ。

use List::MoreUtils qw(any);

my @special_item_ids = qw(10001, 10002, 10003);

if (any { $_ == $item_id } @special_item_ids) {
   ...
}

ってやりがちだけど、

my %special_item_ids = (
    10001 => 1,
    10002 => 1,
    10003 => 1,
);

if (exists $special_item_ids{$item_id}) {
   ...
}

これでいい。リストの数が増えても計算量が増えない。

2012-09-16

[]組み込み関数のStub

CORE::GLOBAL::* でオーバーライドする感じになるかな。

[Perl] 組込み関数を上書きする - Open MagicVox.net

組み込み関数すべてがオーバーライド可能なわけではないので注意。

ttp://d.hatena.ne.jp/gfx/20091213/1260676300


ちなむと time, localtime, gmtime のStubについては専用モジュールの Test::MockTime があるので、そいつを使ったほうが便利なことが多い。

2012-09-02

[]モダンPerl入門に載ってたデザインパターン備忘録

モダンPerl入門 (CodeZine BOOKS)

久しぶりに読み返してみた。デザインパターンの章、最初に読んだときはMoose語に慣れてなかったのでサンプルコードが読み解けなかったけれど、今はMouseにすっかり慣れたので頭にすんなり入ってきた。

以下再読してのメモ


Bridge

  • ある機能を実装するのに直接オブジェクト内に定義するのでなく、それを定義する他のオブジェクトに処理を委譲する
  • 移譲系パターンの代表格
  • これはたまに見る。プラグインの機構とかで。

Chain of Responsibility

  • ある機能を実装する際に複数のオブジェクトがその機能を備えている可能性がある場合に適用する
  • 見たことがない、というか必要なシチュエーションがぱっと思いつかない…。

Composite

  • 複数のオブジェクトに対しての処理と単一オブジェクトに対しての処理に差がない場合に適用
  • jQueryで単一要素を複数要素を取ってきた場合も同じメソッドが呼べるのもCompositeにあたるのかな
$('#foo').html();   // 単一
$('#foo a').html(); // 複数

Factory

  • オブジェクトの作成及び必要な諸処理を使用者側にさせたくない場合に使用する
  • 馴染みのある例でいうとPath::Class::FileがIO::Fileオブジェクトを返すopenwとか
use Path::Class;
my $file = Path::Class::File->new('/path/to/file');
my $fh = $file->openw; # isa_ok $fh, 'IO::File';

Flyweight

  • 毎回インスタンスを作成するのでなく、すでに作成してあるオブジェクトを返すようにして、メモリ消費量を抑える
  • blessは高コストなのでPerlで使えそう

Iterator

  • 配列やそれに類似するデータ構造の各要素に対する繰返し処理の抽象化
  • これはおなじみだね
  • でもなぜか出会うことがないなぁ

Mediator

  • 多数のオブジェクトが絡むアプリケーション内で、それぞれのつながりをハードコードせずに実装せずに使う
  • Bridgeの一種の派生パターン
  • CatalystやAmon2のコントローラーで使用されている $c (コンテキストオブジェクト)もそのひとつ
  • コンテキストオブジェクト以外で使用シチュエーションが思いつかない…どういうのだろう…。

Observer

  • あるオブジェクトに対して何らかのイベントが発生した時に知らせを受け取るような時に使用する
  • JavaScriptのaddEventListenerが代表格といえるのかな
var elem = document.getElementById('foo');

elem.addEventListener('click', fooListener);
elem.addEventListener('click', barListener);
elem.addEventListener('click', bazListener);

elem.click();

Prototype

  • オブジェクトのコンストラクタを呼ばないFactoryパターン

Singleton

  • 1インスタンスしか作成しない
  • 超おなじみ
  • だけど実質的にグローバル変数になるので使いすぎると変数の管理が難しくなる
  • 実装は超簡単
package MySingletonThing;

my $instance;
sub instance {
    $instance ||= do {
      my $class = shift;
      bless +{@_}, $class;
    };
}

State

  • 構造的にはBridgeと変わらない。状態に応じて処理内容を切り替える

Strategy

  • 構造的にはBridgeと同じ。実際の作業をする裏のオブジェクトを切り替え可能にするパターン

Visitor

  • 複数のオブジェクトを渡り歩く処理を追加・変更する

参考

家で積んでるのでこっちも一度ちゃんと読みたい…

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門

2012-08-29

[]同期的に外部プログラムを管理できるモジュールを探している(追記:見つかった)

【追記】PrePANで質問したらいくつか教えてもらったのであとで試す。PrePAN++

http://prepan.org/module/429En4oFdz


こんな感じの探してる。Rubyでいう childprocess にあたるもの。

use Proc::Child; # 架空のモジュール
my $process = Proc::Child->new(qw( perl -e sleep ));

$process->environment('env_name', 'val');

# start the process
$process->start;

$process->is_alive;  #=> 1

# stop the process
$process->stop;

$process->is_exited; #=> 1

AnyEvent::Util の run_cmd とか IO::Async::Process みたいなモジュールがあるけど、コールバックなインターフェイスは他のモジュールから扱いにくい。なんで、↑ みたく同期的なのが欲しい。

2012-08-26

[]String::ShellQuote

ttp://d.hatena.ne.jp/a666666/20090119/1232370087

コメント欄も参考になる

[]ファイル名のエスケープ

motemenさんのKindlenap読んでたら File::Util::escape_filename なるものが使われてた。

$ perl -E 'use File::Util qw(escape_filename); say escape_filename("foo/*bar.txt");'
foo__bar.txt

2012-08-15

[]Test::Deferences

http://search.cpan.org/~ovid/Test-Differences-0.61/lib/Test/Differences.pm#DESCRIPTION

知らなかった。便利


追記:Test::Deepというのもあった

2012-08-11

[]Test::LoadAllModules

知らなかった。

use Test::LoadAllModules;
 
BEGIN {
    all_uses_ok(search_path => 'MyApp');
}

2012-07-31

[]データ永続化したいけどDB使うの大げさすぎ、ってとき

Cache::FileCacheが便利だった。Storableで自前でがんばろうとしたこと全部やってくれた。

[]Log::Dispatchで日付ごとにログを分ける

Log::Dispatch::File::Rolling 使えば出来る。

ttp://d.hatena.ne.jp/unau/20090929/1254182615

http://search.cpan.org/dist/Log-Dispatch-FileRolling/lib/Log/Dispatch/File/Rolling.pm


ってかログ関連モジュールいっぱいありすぎwww それぞれの特徴まだ全然理解できてなくてうけるwwwwwwww

思いつくだけでもこんだけあるwwwww

  • Log::Handler
  • Log::Dispatch
    • Log::Dispatch::Config
  • Log::Minimal
  • Log::Handy
  • Log::Log4perl

CPAN本は確かLog::Handlerだったっけ

2012-07-30

[]jsonをコマンドラインでdecodeする

JSON::XSを入れるとjson_xsというコマンドが付属してくる。

$ echo '{ "foo" : { "bar": [ "baz", "foobar" ] } }' | json_xs -t dumper
{
  foo => {
    bar => [
      "baz",
      "foobar"
    ]
  }
}

Usage: https://metacpan.org/module/json_xs

2012-07-27

[]dbhの再接続管理をするには

調べてみたら DBIx::Connector というモジュールが定番のようだった。nekokak さんが書きなおした Lite 版の DBIx::Handler というのもある。

コードを追いやすいほうがいいので、後者を採用した。

use DBIx::Handler;
my $handler = DBIx::Handler->new($dsn, $user, $pass, $opts);
my $dbh = $handler->dbh;
$dbh->do(...);

dbix::connector dbix::handler

2012-07-22

[]FindBinは別のプログラムから実行される可能性のあるプログラムの中では使うべきでないなと思った話

Path::Class::file(__FILE__)->dirとかで取ったほうがいいと思った。

[]Text::MicroTemplateでwrapを使う

$_mt というグローバルオブジェクトで wrap というメソッドが使える


wrapper.mt

header
  <?= $_[0] ?>
footer

index.mt

? $_mt->wrapper_file('wrapper.mt')->(sub {
  body
? });

呼び出す

Text::MicroTemplate::File->new->render_file('index.mt');

結果

header
  body
footer

それにしても

T::M はテンプレートのシンタックス覚えなくてホント楽だ… 共同作業するデザイナーさんがいる場合にはとっつきづらいのかもだけど…

2012-07-04

[]use warnings FATAL => 'uninitialized';

リファクタとかをしてると未定義値ではまるのはありがちですが、これ宣言しとくと Use of uninitialized ... な警告が出る場所で落ちてくれるので、開発中はよくやります。

2012-06-27

[]Benchmark.pm の出力結果のようにテキストを縦に整列させるには

Text::Table。opts.pm とかでも使われてた。

https://metacpan.org/module/Text::Table

use Text::Table;
my $tb = Text::Table->new(
    "Planet", "Radius\nkm", "Density\ng/cm^3"
);
$tb->load(
    [ "Mercury", 2360, 3.7 ],
    [ "Venus", 6110, 5.1 ],
    [ "Earth", 6378, 5.52 ],
    [ "Jupiter", 71030, 1.3 ],
);
print $tb;
Planet  Radius Density
        km     g/cm^3 
Mercury  2360  3.7    
Venus    6110  5.1    
Earth    6378  5.52   
Jupiter 71030  1.3

2012-06-26

[]存在しないキーにアクセスしたら落ちるハッシュほしい

typoしたとき気づきにくいし、いちいちassert書くのもだるいし。

オブジェクト作ってアクセサ経由で取り出すようにするという手が思いつくけど、それだとネストしたハッシュで使えない。

2012-06-12

[]use 関数への不満

use しようとしているモジュールの中で、パッケージ宣言されてる名前がTypoしてても、use 時に落ちない。メソッドとかにアクセスした段階で初めて顕在化する。

toku_basstoku_bass2012/06/16 04:23use Hoge::Bar;
は、ファイルパスHoge/Bar.pmを表していて、
Bar.pmの中に書かれているパッケージ名とは何も関係ないんです。
単一ファイルに複数パッケージを入れることができるのもそのためだと思われます。

CsideCside2012/06/26 09:28おお、知りませんでした。ありがとうございます。

2012-06-05

[]DBI で select(all|row) でなく fetch(all|row) をあえて使うべきケース

selectrow_array()はprepare()→execute()→fetchrow_array()をまとめたもので,実行速度の差はほとんどありませんので安心して使えます。ただし,同じ$sthを何度も実行するようなケースでは,prepare()を一度だけし,execute()とfetchrow_array()を繰り返したほうが高速になります。

第9回 高速なWeb APIの実装とテスト―Mobage APIを支えるノウハウ(1):Perl Hackers Hub|gihyo.jp … 技術評論社

ほほー。したらば、山ほどのデータを分割して取り出すようなケースではあえて execute()とfetchrow_array() を使ったほうがよさそう。

|