D-7 <altijd in beweging>

Day to day life of a Perl/Go/C/C++/whatever hacker. May include anything from tech, food, and family.

2008年03月

年末前後からApache::Testで真面目にテストを書き始めている。

ところが全くドキュメントがないんだね。いや、あるんだけど、携帯の機能を使いたいだけなのにあの厚いマニュアル読むの?みたいな感じで。まぁというわけでとにかくざくざくっとドキュメント読んでテスト書いてたらようやくなんとなく分かってきた。この間ある程度他人にも説明できたので自信ついたしw

Apache::Testはmod_perlハンドラをテストするときに使う。ディストリビューション等でmod_perlをテストしようと思うとApache自体を立ち上げたりなんだりしなければいけなくて「一体どうテストすればいいんじゃ?!」となりがちだが、Apache::Testを使うと、
・・・などなどを行ってくれる。

これだけの事を行うのに色々と手続きが必要だと思いがちだが、そこはそれ、Laziness is a virtueと言い切るPerl界のハッカー達が作ったフレームワークである。超絶簡単。

まず、Makefile.PLの中身を書き換える。残念ながらModule::Installのようなクールなヘルパーは使えず、Apache::TestMMというExtUtils::MakeMaker互換のものを使う必要がある。書くのは以下のような内容:
use strict; use ExtUtils::MakeMaker; use Apache::TestMM qw(test clean); Apache::TestMM::filter_args(); Apache::TestMM::generate_script('t/TEST'); my %INFO = ( NAME => 'MyApp', ... ); WriteMakefile(%INFO)
これだけ。Apache::TestMMを呼び出して、filter_args()/generate_script()を呼ぶ。

上記のMakefile.PLを実行するとt/TEST.PLというファイルをパース、t/TESTというスクリプトを作成する。それとMakefile内にこのTESTを使ってテストを走らせるための設定がされる。

TEST.PLというファイルはもう定型でよい:
use Apache::TestRunPerl; Apache::TestRunPerl->new->run(@ARGV);
以上!あとはmake testするとApache::Testがよきようにはからってくれる。すばらしい。

さて、テストの中身だが、これは何をテストするかによってちょっと変わってくる。

まずハンドラ内で何かをテストする場合。例えばハンドラ内でなにかのオブジェクトを作成し、メソッドを実行した結果をテストする場合。その場合はHTTPリクエストを送るクライアント側はリクエストを送る以外何もする必要がない。普通だったら、
use strict; use LWP::Simple; get('http://localhost:8529/path/to/url');

みたいな.tファイルを書きたくなるが、まずテスト用Apacheのポートをハードコードしたくないし、それにそこはそれ、Laziness大好きっ子だから、ハンドラを書いたらただリクエストを送るだけのファイルなんて書きたくないよね?そういう場合はt/responseというディレクトリを作って、その中に適当にハンドラを突っ込む。すると、.tファイルを全て自動生成してくれるのです!

例えばこんなハンドラをt/response/MyApp/FirstTest.pmというファイルに入れておくと
package MyApp::FirstTest; use strict; use Apache::Test qw(-withtestmore); use Apache2::Const -compile => qw(OK); use MyApp::Object; sub handler { my $r = shift; plan($r, test => 2); my $obj = MyApp::SomeObject->new(); ok($obj); is( $obj->foo(), 'foo' ); return &Apache2::Const::OK; }
t/myapp/firsttest.tなんていうテストファイルを作ってくれる。内容はこれだけ
use Apache::TestRequest 'GET_BODY_ASSERT'; print GET_BODY_ASSERT "/MyApp__FirstTest";
このようにハンドラを作っておくと勝手にリクエストを送るところまで自動生成してくれるわけだ。しかも嬉しい事にmake testを実行する時点でtディレクトリ内にt/confというディレクトリが作られ、その中にhttpd.confが作られる。当然このt/response内のハンドラもそこに自動登録される。自動生成されたt/conf/httpd.confにはこんな感じの記述がされ、apacheからの呼び出し可能になっている
<Location /MyApp__FirstTest> SetHandler modperl PerlResponseHandler MyApp::FirstTest </Location>

make testを走らせるとクライアント側でテストフレームワークが走っているはずなのにテスト的なコードはハンドラ側にしか無い事にお気づきだろうか。実はこれ、MyApp::FirstTestの中でok()等を呼び出すとTAP形式の出力をクライアントに送り、それを自動生成されたテストスクリプトが解釈する、という仕組みになっている。

さて、これまでの説明した時点でt/ディレクトリの中はこんな感じになっている
t/response/MyApp/FirstTest.pm t/myapp/firsttest.t # 自動生成 t/conf/apache_test_config.pm # 自動生成 t/conf/httpd.conf # 自動生成 t/conf/modperl_inc.pl # 自動生成 t/conf/modperl_startup.pl # 自動生成

基本的にハンドラのテストに関してはあとはt/response/の中にハンドラモジュールを足して行くだけである。

万が一ハンドラの設定等をhttpd.conf内から指定したい場合は上記ファイルの他にもう一つextra.conf.inというファイルを作ると良い。たとえば、MyAppVar という変数を設定したい場合は以下のようなファイルを作り、t/conf/extra.conf.inに保存する。
<Location /MyApp__FirstTest> PerlSetVar MyAppVar "foo" </Location>

extra.conf.inはmake test時にパースされ、一部情報が置換されたあと、t/conf/httpd.conf内からIncludeされる。これで設定が反映されるわけだ。らくちん!

ここまではハンドラ内でテスト実行する際のやりかたでした。でもハンドラ自体は作成されていて、しかも部品別に分けてさきほどまでの方法でテストできない場合、クライアント側からその動きを確かめる必要がある。その場合は先ほどのextra.conf.inにハンドラを追加登録すると良い。
<Location /path/to/myapp/anotherhandler> SetHandler modperl PerlHandler MyApp::AnotherHandler </Location>

これに対して例えばt/anotherhandler.tというクライアント側のスクリプトを作る
use strict; use Apache::Test qw(:withtestmore); use Apache::TestUtil; use Apache::TestRequest 'GET_BODY'; use Test::More ( tests => 1 ); use URI; my $url = URI->new("/path/to/myapp/anotherhandler"); $url->query_form( foo => 1, bar => 2 ); my $data = GET_BODY $url; ok t_cmp($data, ...., "data okay");

GET_BODY等の関数はApache::Testフーレムワークが提供してくれるユーティリティ関数。GET_BODY等は先ほどの自動生成された設定を理解しつつ(ポート番号とか)リクエストを実行する。t_cmpは様々な構造体を理解してくれるツールだ。詳しくはApache::TestUtilを見た方がよろしいな。

こうして実行されたテストのログはt/logsに格納されるので、問題があったらそちらのerror_log等を参照すると良い。

さらに、デバッグ方法としては、t/TESTを使うという手もある。Apache::Testでmake testを実行する時はt/TESTが裏方で実行されているので、テストを単体で実行する時やその他の細かい捜査をしたい場合はそのスクリプトに引数を与える。よくあるのが「テスト実行時のサーバー側のレスポンスが知りたい」という状況だ。この場合は、以下のようにしてテストを実行する。
./t/TEST -verbose t/anotherhandler.t # これで標準出力にレスポンスを表示する

さあ、以上が分かればmod_perl上で動くソフトウェアのテストもばっちりだ。もう「mod_perl用のテストなんて書けません」なんて言えませんね☆
    このエントリーをはてなブックマークに追加 mixiチェック

(以下、自分はそれほど酒の味の表現とか歴史に詳しいわけでもないので、味の表現等筆者がそう感じている、という程度の認識でお願いします)

Longmornというスコッチがあるわけですよ。Longmorn自体についてはここが詳しそうだ(正直ある程度の知識は好きだが、あんま酒の歴史は興味なかったりする)。Longmornはまろやかな深い味と果実のような香りが素晴らしいスコッチで大好きなんだが、マイナーなのでいかんせんあちこちにあるわけではない。まぁマイナーっつっても別にもう作ってないわけでもないから手には入るけどね。

この間とあるバーに行ったら「木曜に来ると良い酒置いてあるよ」とわざわざ教えてくれたので金曜日に行った訳です。そしたらでてきたのがLongmornの42年。

普通スコッチと行ったら12年から18年、長期熟成の物でもだいたい24年前後。基本的に熟成期間が短ければ短い程熟成から来る香りが抑えめでアルコールのアタックが直接舌に来る。24年くらいの熟成だとアルコール分が飛び始め、まろやかな味に変貌し、なおかつ樽からうつる香り、熟成による香りが漂い始める。

なので下手な長期熟成ものを飲むと、香りだけでスコッチ特有のあの味の強さがなく、すかすかの味になる事もある。まぁそこまでいかなくとも微妙なバランスの上で成り立っているので長期熟成ものほど良い、というのはちょっと違う。

が。このLongmorn 42年。1960年代に樽詰めされたものなので俺は生まれてもいない。そんな頃にスコットランドのどこかで作られた酒だ。なのに飲んだ時のこの力強さ!バー中に漂う香り!味王でなくとも巨大化したくなるウマさ。すげぇ!

こいつ、ショットが4500円と値段もロケット級だが、スコッチ好きなら一回飲む価値はある。

ちょっと余談気味だが、酒に関しては味と値段のバランスさえ合ってれば、高い酒を飲む価値があると思う。お金を投資する価値がある。なぜなら酒は二度と同じ物には出会えないから。特に10年超の長期熟成が必要なスコッチのような酒は、蒸溜所そのものが無くなっている事もよくある上、どちらにしろ当時の材料を含めた環境を再現できる事は少ないから。

数十年かかるという手間と、2度と同じ酒に出会えないという事を考えると、このLongmornは興味がある人は是非飲んでみてほしい。値段との兼ね合いで自分は多分もう一回飲めたからおかわりはいらないが、スコッチ好きには超おススメ。
    このエントリーをはてなブックマークに追加 mixiチェック

こんな事言われてるから補足しておくです。

2008年03月07日 K-Ono K-Ono 日本人がアメリカの大学の工学部に入学さらに卒業してしかも就職できていて「落ちこぼれ」とは方腹痛いわ。ふざけんな。

  1. 俺は元々海外住まい。今年31歳になるけど、そのうち21年間海外です。だから日本人というより外人に近い。DNAは100%日本人だけど。アメリカ人がアメリカの大学に入れても全然すごくないよね?ちなみにアメリカの大学、大学を選ばなければ英語喋れる外人はいい金づるだから結構さくさくと取ってくれるんだな。
  2. 就職はできたけど、決め台詞はなんだったと思います?面接の時に「最低賃金で良いからやとって!!!」って懇願したんだよ。それまで半年以上無職でした。ちなみにその時の最低賃金は$6.50/時

ちゃんと書いておくべきでしたね。すみません。
    このエントリーをはてなブックマークに追加 mixiチェック

色んなところで自分の今までの経歴を話す時に話してるけど、俺は基本的に落ちこぼれです。大学は工学部でComputer Scienceを専攻したけど、イマイチぱっとせず、基本中の基本みたいなコースも落とした事あるし、授業なんて(アメリカの大学なのに)全然出てなかった。自分の専攻のクラスはさすがに退学にされたくなかったんで出てたけど、それ以外の数学、経済、化学、物理、ことごとく出席日数は50%以下だ。物理なんて全行程を通して2回しか出てない。

特に創造力があるわけでもない。若かりし頃、高校生とかその頃は漫画家を目指してみたり、ミュージシャンを目指してみてレスポールを膝くらいの位置に吊って弾いてたりしてみたけど、結局そういうシナプスがばりばり音を立てて何かをゼロから生み出すような事もたいしてうまくなかった。

だから正直大学卒業間際は相当焦ってた。卒業後紆余曲折あって、2年後くらいにNetwork Applianceという会社に入社できた時もまだ何も出来ず、俺はいつクビにされるんだろうと悩んでいた(まぁ、それとは別に俺は別にコンピューターの仕事をしなくても飯を食う分くらいには金は稼げるだろうという楽観的な意見もあったのだが)。

卒業後 からひどい貧乏なアメリカ生活を送っていたからその生活には戻りたくなかったし、かといって俺は使えない人間だったから仕事もあまりないし・・・。そんな状況で出来る事と言ったら一つしかなくて、それは自分でやる事を見つけて、とにかくそれを愚直に突き進めて行く事だけだった。

当時社内に初期開発後しばらく忘れられていたツールがあって、それが何かの話のおりに話題にあがったので、ふと興味を持ってそのツールを見てみる事にした。なんせ仕事ないしな。

ソースコードを読み解く事数日、どうにかこうにかなんとか何をやろうとしているのか分かってきたので、その時になっておずおずと当時のボスに「これ・・・動かせるようにしてみてもいい?」と聞いた訳です。返事は「おお、いいよいいよ」別になんの期待もなさそうだけど、そりゃそうだろ。仕事もねぇしw

そのツールは結局2ヶ月近くかかって動かす事に成功した。実はその間に日本に強制送還、もとい、ビザが切れたので日本支社で働く、というような事になってたりしたので微妙な環境だったのだが、それでもリモートから作業してなんとか動かした。

このツール自体はその後数年間運用されて、結局政治戦争に敗北した我が部署が乗っ取られたのでスクラップになったのだが、まぁそれはともあれ、この時自分は21か22。その語2年前後でCPANにモジュールを登録したりするようになっている。

ちなみに俺のような人間がCPANに出会えたのは幸運以外の何者でもないと思う。自分の才能のなさをどうしようというときに、自分がただのでくの坊だとさえ認められれば、「あとはCPANから借りてきました><」で自分の作りたい物が作れて、仕事になる。時々見つける事のできる細かいエラーとかを報告すればそれはそれで貢献できる。あきらかにWin-Winじゃんね。

ともあれPerlやCPANとの出会いはそこからだし、やはり明らかにターニングポイントはその掘り起こしてきたツールだったなぁ

学校を卒業して11年たった今、自分が「すごくなった」って全然思わない。今でも上に人がいすぎて(しかも最近は若い人がどんどん自分の上に来るし)悲しくてしょうがない時もあるし、なにより自分の才能を自分が信じてない。

そのかわり自分はでくの坊だと認められた。そしてその後はただひたすらコードを書いてきた。それだけは自分の自信につながってきてる。

天才でない人は愚直に書く、ノウハウをつける、積極的に手を動かす。人の意見を素直に取り入れる。これしかないんだと思うよ。才能の無い人が出来る事はそれだけだけど、それを続ければ何かが実るはず。

今は必死で手を動かしてるときっと後で戻ってくるものがあると、天才ではない、大多数の後進の方達には言ってあげたい。
    このエントリーをはてなブックマークに追加 mixiチェック

前のエントリで調査した結果、Text::MeCab に深刻なメモリーリークが発見されました。

メモリを解放する処理自体は問題なく呼ばれていたのですが、そのタイミングがperlプロセスが終了する時点まで待たされている状態でした。最終的には確実に解放されていたのでなかなか気づかなかったのですが、node->nextやnode->prevのような関数を呼ぶとperlが終了するまでメモリが解放されませんでした。特に形態素解析する文章が巨大な場合、これは一瞬でメモリリークとなり、問題が顕在化します。

先ほどアップロードした0.20005でこの不具合を修正してありますので、CPAN登録が済み次第アップグレードを推奨いたします。急いでいる場合はcodereposからも入手できます。

ちなみに最終的なフィックスの決め手はXML::LibXMLのソースコードを読んだ事でした。自分は愚直にsv_blessという関数を使ってオブジェクトを作成していたのですが、XML::LibXMLではsv_setref_pvという関数で同等の事をしていました。とりあえずperlgutsを読み、このsv_setref_pvを使用したところ一瞬で問題が解決した次第です。matts++, pajas++
    このエントリーをはてなブックマークに追加 mixiチェック

いわゆるCPANモジュール形式で展開されているモジュールに対して一般的に行う以下の手順:
perl Makefile.PL make make test make install # 以下はモジュール作成者のみが気にするであろう make clean make disttest make dist make manifest

これがそれぞれ何をしているのかって案外しられてないのかもしれない。

perl Makefile.PL - これはMakefile.PLを単純に実行している。この中では一般的にExtUtils::MakeMaker、Module::Build、Module::Install等のモジュールが使用され、インストールに使うMakefileというファイルを作る。これはmakeコマンドが自動的に検知して、使用してくれる。ちなみにmod_perlでテストを作成する時に使うApache::Testフレームワークの中ではApache::TestMMというような物がその代用をしたりする。

Makefile.PL内で使用しているモジュールによっては挙動に違いがあるかもしれないが、だいたいこのMakefile.PLを動かした時点でMakefileにインストール対象となるスクリプトやlibディレクトリ内に存在するモジュールのリストを作り、これ以降はそれらのファイルに対してのみ作業を行うようになる。

makeフェーズはこれがCで書かれたプログラムだったりするとコンパイルが始まったりするのだが、Perlでは基本的にファイルの移動とちょっとしたフィルタリングを行うだけで終わる。

基本的な動作としては、blibというディレクトリが作られ、lib内にあるモジュールがblibへ、実際にインストールされた状態と同じレイアウトでコピーされる。blib 内を見るとautoやらなにやら怪しげな名前のディレクトリができてるかもしれないが、その辺りはXSでコードを書いていたり、AutoLoader等の黒魔術的な魔法を使ってなければ無視して良い。

インストールするスクリプトを指定していた場合は、そのスクリプトの#!ラインがMakefile.PLを動かした時のperlのパスで書き換えられる。/usr/local/bin/perl Makefile.PLとやっていたら、#!/usr/bin/perlとなっていたものが#!/usr/local/bin/perlに書き換えられる。これもblib以下にとりあえず格納される。

あとはそれぞれのモジュールやスクリプトからPODを抽出してman化したものを作ったり。

blib内のファイルレイアウトを明示的に使用するにはblibというプラグマを使う。これを使用すると開発者モードのようなものがオンになりblib内のファイルレイアウトを理解した上でperlを実行できる(開発者モードと言ったって、blibのレイアウトを理解してくれるということだけだが)。だからmakeを通さずにt/内のテストを動かすにはperl -Mblib t/test.tとかする。これでblib内のモジュールを使いつつ、t/test.tを実行できる。

このblibにモジュールを入れるという作業が結構キモで、インストールする時はともかく、自分のモジュールを開発している時はエラーになったりするので注意が必要。makeの次のフェーズであるmake testで使用されるディレクトリはlibではなくblib内だからだ。

だから例えば、make を通さないでperl -Mblib t/test.tとかを実行していると、その途中でlib内に変更を加えてもテストには反映されない。いつまでたっても古いコードしか実行されなくて首をかしげる事になるだろう。それは単純にmakeを行っていないのでlibの中身がblibに反映されてないからだ。

同様にたまにlibにファイルを追加したのにいくらmakeを行ってもblibにその中身が反映されず、結果make testが落ちる。これはMakefileの中にモジュールのリストが書いてあったりするせい。Makefileでどのファイルをlibからblibにコピーするのか指定されていると、Makefile.PLを実行した時にlibディレクトリになかったモジュールは無視されてしまう。この場合は色々対処法があると思うが、個人的には素直にmake cleanして(後述)perl Makefile.PL、make、make testと行うのが良いと思う。間違いがないから。

make cleanは読んで字のごとし、ディレクトリ内を掃除してくれる。主にblibの中身を消してくれたり、その他一時ファイルを消してくれる。Module::Installはincの中に色々とメタデータを入れたりするのでそれを確実に消したい場合はこれを実行するといい。あとMakefileも削除されるので、再度作業するにはperl Makefile.PLが必要

make manifestはMANIFESTファイルを作る。MANIFESTファイルはCPANにあがっているディストリビューション(いわゆるCPANモジュールのtar ball)内に入っているべきファイルのリスト。ディストリビューションに必要なファイルが全部揃っているかどうかはこのファイルと実際に格納されているファイル群を比べる。

make manifestを実行すると、基本的に現在のディレクトリ以下に格納されている全てのファイルをMANIFESTに追加する。.svn等の隠しファイルは無視されるが、それは良く知られている隠しファイルだけ。あとは全て追加されてしまうのでMANIFEST.SKIPで指定するか、一度MANIFESTを作ってしまったら手動で削除しないといけない。必要なファイルのみをMANIFESTに追加しないと、この後のmake dist/disttestフェーズで問題が出てくる

make distとmake disttestは最終結果であるディストリビューション用のtar ballを作るのに使う。基本的な動作としては"MyModule"のバージョン"0.01"というディストリビューションを作っている場合、現在のディレクトリにMyModule-0.01というディレクトリを作成し、ディストリビューションに必要なファイルを全部コピーする。そしてこれはtar + gzipでtar ballを作成してくれる。

make disttestは最後のtar ballを作成する動作の代わりに、該当ディレクトリ内でmake testを走らせてくれる。これで開発ディレクトリ以外でmake testを動かした時の動作を確認できる。

気をつけなければいけないのはmake distがディレクトリにコピーするファイル群は、MANIFESTに記されているファイルである、ということ。だから例えば必要なファイルなのにMANIFESTに入ってなかったり、不必要なファイルがなぜかMANIFESTに存在していても、MANIFESTに書いてある通りのファイルがコピーされる。余計なファイルがあった場合は恥ずかしいだけだが、ファイルが足りない場合はmake testでこける事が多いのでちゃんと確認すべきだ。そのためにもディストリビューションを作成する場合はmake disttestは必須ステップと言える。

と、こんなところかしら。なんか間違ってたら突っ込みいれてください。




    このエントリーをはてなブックマークに追加 mixiチェック

Text::MeCabがおかしい。某社社内より報告アリ。毎度ありがとうございます。

で、すでに数時間そのコードとにらめっこしている。なぜ思い通りに動かないのかよくわからない。根本的な問題はわかった。Text::MeCab::NodeオブジェクトがDESTROYされるのがなぜかスコープを脱出した時ではなく、Global Destruction時のタイミングで起こっているのが問題。

どういうことかというと、Perlは2つのタイミングでガーベッジコレクションを行う。ひとつはステートメントとステートメントの間(スコープが変わる時も含む)、そしてもうひとつはPerlのインタプレタ自体がメモリから削除されるGlobal Destruction時。

現在のText::MeCabでは、以下のように$nodeオブジェクトをどんどん変更して行っても、さっきまで入っていたオブジェクトのDESTROYが呼ばれずに、次のループに行ってしまう。そしてGlobal Destruction時に大量のDESTROYが走る。

my $mecab = Text::MeCab->new(); for(my $node = $mecab->parse($string); $node; $node = $node->next) { # do whatever }
でもこれだと(当たり前だけど)、for()内、いや、プログラムが終了されるまでメモリが解放されることがない。これでは駄目なのだ。SvREFCNT_incやSvREFCNT_decを色んなところに入れてみたんだけど、唯一正しいタイミングでガーベッジコレクトされるのは最初からSvREFCNTを0にしてしまう方法だけだった(これは当たり前のようにエラーがでる)

いったいどうすればいいんだ・・・?誰かヒントを・・・
    このエントリーをはてなブックマークに追加 mixiチェック


後半その通りなわけですが、CatalystはModel::DBIC系のせいでMVCが誤解されてるのよねー

と言っておられる。たしかにその通り。「モデルってDBでしょ?」みたいな印象が一般的にあると思う。

そういう印象を持ってる人に説明すると、「モデルを作る」って何かというと、DBのようなストレージにあるものをどうこうする、ではなくて「データに対する操作を抽象化したものを作る」ということです。例えば、ブログを作ると、Blog、BlogEntry、BlogUserみたいなモデルを作ります。そしてその操作方法はこんな感じ:


# ブログを登録するみたいなAPI MyApp::Model::Blog->create({ user => $blog_user, title => $title, .... }) # その後どこかでエントリを作るようなAPI my $blog = MyApp::Model::Blog->find_by_id ( blog_id => $id ); MyApp::Model::BlogEntry->create({ blog => $blog, title => $entry_title, content => $entry_content });

こんな感じ?見て分かる通り、裏ではDBを使ってるかもしれないけれども、モデルという概念はそれより上の概念。ストレージも含め、ブログエントリを作成する時に行われる全てのステップ(ビジネスロジック)をカバーするのがモデルだ。例えばブログエントリを書く時にHTMLのフィルタリングをするとか、他のサーバーにアクセスしてなんらかのRESTで話すとか、わかんないけど、とにかく「エントリを書く」という行為を抽象化できるところがモデル。

じゃあ元々のブクマコメントのModel::DBICはどうすんだよ、いらないのかよ、みたいなところに行き着くかと思うのだが、そこはそれ、モデルに「格納先」を指定するのにDBを抽象化したModel::DBICを使ってやる、っていう手もある
my $c = shift; # Catalyst的なcontextがあると仮定します MyApp::Model::BlogEntry->create({ storage => $c->model('DBIC::BlogStorageSchema'), blog => $blog, title => $entry_title, content => $entry_content });

これで全く問題なくDBICの良いところを使える。

要はDBICはRDBMS特有ストレージのモデル的抽象化であり、本来は他のビジネスオブジェクトの裏で消えているべきところが、実際にはものすごくよく使うものだから同レベルでのモデルが存在する、というそれだけの事。

あなたがこれから書くCatalystアプリはDBICを使うにしてもControllerから直接の呼び出しは避けましょう。それは本来抽象化されているべきことです。そういうふうに組み立てて行くとうまく密結合を防ぐ事ができるはず。
    このエントリーをはてなブックマークに追加 mixiチェック

最近ソフトウェアエンジニアリングに置ける開発手法に関して考えている。

ぶっちゃけ言ってしまうと「やっぱりTDDっぽいのがいいな」というところに落ち着きつつあるのだが、厳密にTDDをしたほうがよい、と思ってるわけではない。TDDとかExtremeプログラミング、Agileプログラミングにしても理想はいいんだけど、原理主義っぽい使い方は現実にそぐわないと思ってるからだ。

前置きはこれくらいにしておいて・・・重要だと思うのは以下の点:

  1. 開発サイクルに自動テストツールを組み込む
  2. エンジニアによるバグ/不具合発見時には「動かない」は許可しない。必ず再現コードを提出してもらう
  3. テストを自動テストツールを組み込む(=次回リリース前にはかならずテストを実行できる状態にする)
  4. テストが通るまで修正を続ける
という開発サイクルを取るべきだ、という結論に落ち着きつつある。

当たり前と言えば当たり前なんだけれども、開発をしている人はバグを例えば口頭で説明されたらその場で直して「直したよ!」って言って終わっちゃう事も多いので、そういう事を回避したい、という思いから上記サイクルを強く推奨したいのだ。

開発エンジニアとしてはバグを修正するために製品コードに手を入れるのは簡単だ。でもマーフィーの法則ではないけれども「一度起こったバグは必ずもう一度起こる」と俺は信じている。他のコードに手を入れた瞬間か、バージョンアップ時にコードを書き換えた時か・・・とにかくバグは起こるべくして起こる。

でもテストを作成せずに製品コードに手を入れてしまった瞬間、そのバグが起こったという事実さえ記録に残らない。次回起こるかどうかチェックができない。「なんでまた起こったんだ?」というクライアントの問いに答えられない。

それらを解決するのはリグレッションテストを増やす事しかないと俺は考えている。

とにかくあれだ、make test必須ってことだ。t/ディレクトリの中がt/regression-*.tというファイルで埋まってる状況こそ望ましいはずだ。世の諸君、テストを書くんだ!

さてここからは余談だが、そういう事を踏まえるとMVCを使う別の理由が見えてくる。

MVCは一般的にコードとプレゼンテーションを分けるのに使う、と言われがちだが、MVCパターンを使う事によって以下のようなシナリオを防げる:

  1. Webアプリで不具合発生
  2. 修正するも、テストが書けないとエンジニアに言われる
  3. 「なんで?」と聞いても「Webサーバを通さないとテストできないから」「うちのネットワーク構成だと本番サーバーにアクセスせざるを得ない」とか言われる
  4. テストがない状態で運用。将来また問題が起きないかどうか((((;゜Д゜)))ガクガクブルブルしながら過ごす
それがどうMVCとだと解決できるかというと、WebアプリがうまくMVC構造になっているとロジックがほとんどモデルに落ちてくる。

するとモデルは当然Webサーバと結合してない(べき)なので単体でテストできる!

やった!テストできるじゃん!

ちなみにモデルなら・・・と書いたけど、Catalystのような構造になっていればCだってVだって同じようにバラして単体テストできる。

そういうわけでMVCの利点を話す時は旧来の利点だけでなく「テストが容易に書ける」と足したほうがいいと思う。

世の諸君!テストを書くんだ!ボーイズ・ビー・アンビシャス!どげんかせんといかん!All Your Tests Are Belongs To Us!

# 最後わけわからんくなった。
    このエントリーをはてなブックマークに追加 mixiチェック

Cache::Memcached::libmemcachedの0.02000をリリースしました

このバージョンからMemcached::libmemcachedを継承するようにしており、前バージョンより約10%前後のパフォーマンス改善が見られます。概ねCache::Memcachedの6〜8倍のスピードで動きます。Cache::Memcached::Fastとの差はget_multi()以外は5〜10%程度libmemcachedのほうが速い感じ。get_multi()はいまだになぜかFastより遅いです。理由はよくわかりません・・・

機能要望等ありましたらお気軽に連絡してくださいまし。
    このエントリーをはてなブックマークに追加 mixiチェック

なんかまわされてきたぞー

  1. 酔うと基本的にどうなりますか?
    • 外見:顔の色がすぐかわる。赤→深紅→青。青になると危険
    • 行動パターン1: 下ネタ開始。最近のはまりネタはソーセージ。
    • 行動パターン2:そでをまくりはじめ、オヤジモードON
    • 行動パターン3:キス魔になる。一応空気は読めると思うが。ちなみに男女問わずこの状態ではキスできる。
    • 最終形態:これは絶対に心を許してる人の前でしかならないけど、泣くこともある。これはあんま見せた事ない。
    • でも多分俺は基本的に「普通」のよっぱらいのような気がする
  2. 酔っ払ったときの最悪の失敗談は何ですか?
    麻布十番で初対面の人達8人くらいと飲んでる時に、焼酎が原酒だということを計算にいれずに飲みまくり、ゲロゲロしてしまったこと・・・かな。酒飲みにあるまじき失態。しくしく
  3. そのときはどのくらい飲みましたか?
    なんか強い(40度くらい)の焼酎原酒をそのままストレートで10杯くらい飲んでたんだよなぁ。ちなみに失態をさらして別れた後その後すぐ素面に戻って飲み直したのはナイショだ。
  4. 最悪の二日酔いはどんな感じでしたか?
    朝東横線→日比谷線と満員電車に揺られながらもなんとか六本木ヒルズまで辿り着いたのにとうとう我慢しきれずに一階のトイレでゲボゲボして、結局その日休んだ。・・・一番ひどいわけではないが、我慢しないといけない状況が1時間弱続いたので思い出としては最悪の部類に入る。
  5. 酔っ払って迷惑かけた人にこの場で謝りましょう
    ヨッパライ仲間の人達は「酔ってる時はしゃあないべ」で済むのでよいとして、やっぱり一番迷惑かけたのは問い3の人達だな。すみません、すみません。
  6. 冷蔵庫に入っているお酒の量は?
    冷蔵庫にはあんまり入ってないなぁ。今はタリスカーと余市と黒霧島が冷蔵庫の脇にあるよ。ビールは飲みたい時に買ってきてる。夏になったら多分金麦のケース買いを再開します。
  7. 好きな銘柄は?
    • Port Ellen
    • Auchentoshan
    • Bowmore
    • Talisker
    • ビールはモルツかキリンラガーでお願いします。
    • ベルギービールはやっぱり Chimayですね
    • 日本酒は広島の「神髄」とか福島(福井なの?すみません)の「黒龍」が好きですが、最近さわやか系に走ってるんで澤之井とかでも全然おいしくいただけます。
  8. 最近最後に飲んだお店は?
    中目黒「まんてん」。ホルモン食いながらぐびぐび
  9. よく飲む、思い入れのあるお酒5品
    酒自体にあまり思い入れはないが・・・元彼女達と一緒に飲んだ酒といえば「Chimay」「マンハッタン」「Laphroig」あたりでしょうかね。
  10. バトンのジョッキを渡す人
    • 酒飲みっつーとid:osawa? うさぎのぴょん子?ぴょんこはすでにやってそうだな。
    このエントリーをはてなブックマークに追加 mixiチェック

080302_1941~0001.jpgひょんなことから今日は新宿でやってる今敏の個展のようなものに行ってきた。昨日からやってるんだけど、普通に覗いて終わりにしようと思ってたらなんと本人がいた!わ!

ってこと「PERFECT BLUE」のDVDを購入しサインもらってきたのです。しかも絵つきだ!わーい。ちなみに、これを描いているのを見ていたわけだが、線を描くのにまったく迷いがない。すげぇきれいに線が引かれて行く。

備考:今敏は思っていた以上にでかい。

PERFECT BLUEは初めて見たけど、おもしろかった。
    このエントリーをはてなブックマークに追加 mixiチェック

  • S社のAさん来社につき、ついでに飯を食いに行く事に。いや、酒を飲みに行くの間違いか。
  • ソーセージに関して大いに盛り上がった。
  • 終電が心配なので割と早めに解散
  • 帰りの電車で降りたらdropd...もといSさんと遭遇。正直すげぇ最近までネットのアイデンティティとSさんが合致してなかった。改札でるまで雑談。
  • 飲みが足りないので地元でシガー&モルト。オーヘントッシャン。シガーはちょっと贅沢な吸い方をしてしまった。最後はインセンス代わり。

    このエントリーをはてなブックマークに追加 mixiチェック

このページのトップヘ