Home > C::M::App Archive
C::M::App Archive
CGI フレームワークブーム
- MENTA というウェブアプリケーションフレームワークをかいてみた - TokuLog 改めB日記
- NanoA というウェブアプリケーションフレームワークをかいてみた - id:kazuhookuのメモ置き場
- YappoLogs: Yacafi という軽量CGIフレームワーク書いたよ
すべてに共通していえることは
- コンセプトがはっきりしている
- コード短い
一方オレオレフレームワークである C::M::App は、わりきりが足らず、肥大化している (現在約 700 行) orz
1 年以上使ってきて、自分にとって実用的な部分、足りていない部分、使わない部分が見えてきたので、ばっさりシンプル化することにした
- db 関連部分は別途書くことがほとんどなので、ばっさり削る
- request の dispatch 部分もいつも同じことしかしないので、なんでもやろうとせず、ルール化してばっさり削る
- 現状公開していないことだし、互換性は考えない。名前変える
この 3 つをやるだけで、多少シンプルになるはずなので、今の仕事が一段落したら Perl 脳に戻してとっととやる
- Comments: 0
- TrackBacks: 0
C::M::App のテストケースを書き始める
つうか、整理する
ぜんぜん Minimal でなくなったので、テストケースも肥大化
↓
途中で面倒になってテケトウなテスト
↓
こりゃ配布できんわ <= 今ここ
というわけで、書き始めたわけでも整理し始めたわけでもなくて、整理しようと決心しただけ
- Comments: 0
- TrackBacks: 0
実装予定メモ
Cookie 食べたりするのに手で書くのが面倒になったので、CGI::Cookie ぽい何か07/01 完了- ついでに Session 管理っぽいこともできると楽しいかな
- db 関連は C::M::A::DBI として実装したので、C::M::App からはバッサリ消す
- ところどころにある日本語コメントをなんとかする
- C::M::A::Util の整理
- Comments: 0
- TrackBacks: 0
使うものじゃなくて作るもの
via New Generation Chronicle:開拓者から改革者へ ネタで未来を切り開く男 大沢和宏 (2/6) - ITmedia エンタープライズ
メリットは、自分で作ってるので手足のように使える、Catalystとかの嫌な部分が体感できた。そんな感じです。やっぱりフレームワークは使うものじゃなくて作るものだと思うので、そろそろSoozyの次の別のフレームワークを作ろうとしています。
非常に納得。手前味噌ながら、一年以上日記では触れていないCGI::Minimal::App、自分で作ったものだけに、日常使いに最適! 自分で作ってるから、自分が好きなように直し放題! 公開していないので本当にいじり放題! そして、公開前に飽きてきた!
つっても次のフレームワークを作るかというとそこまでの気持ちはなくて「如何に日常書くコード量を減らしてギター弾く考えることに時間を使うか」ということをやるためには、まだまだ C::M::App には進化してもらわなければならない
- Comments: 0
- TrackBacks: 0
フレームワーク (12) - 悩み中
メール送信関連の実装、と言うのは簡単だが、まじめに作るとそれだけでフレームワークになってしまうので、どの程度で妥協するのか悩み中
- メール本文はテンプレートファイルで。テンプレートファイル名を指定しない場合のルールを決める
- From, To, Subject は設定ファイルに書くなりどっかから持ってくるなり、なんなりするが、テンプレートエンジンは通す
- 7bit ISO-2022-JP 決め打ちにしよかとも思ったが、イマドキの MUA なら 8bit UTF-8 で大丈夫かな? 携帯電話はまずそげ。まぁ、無難に 7bit JIS にしとくか
- 添付ファイルや HTML メールは、いらね
などと考えて「普通のメールを無難に送るだけのメソッドをおまけ的に実装」することにした
メールの実装終わったら、次は validation を考えることにした。ものすごく楽したくて、ものすごく手を抜けない部分なので、じっくり考えよう
- Comments: 0
- TrackBacks: 0
フレームワーク (11) - config 関連実装完了
明日以降の実装のためのメモ
YAML ファイルの runmode 名と同じ項からいろいろ取得、というところまで仕様にするとやりすぎかなとも思ったので、prerun モードで実行するから不要なら上書きしてね、というスタンスにした
あと、実行可能な runmode を指定するホワイトリスト形式は安全でいいんだが、ちょっと作ってみるって時に面倒なので、ブラックリスト形式にした
- 予約語=C::M::App のメソッドの場合は実行しない
- アンダースコアで始まるメソッドは実行しない
- それ以外のメソッドは全部実行する
という感じで
存在しない runmode を指定した場合は 404 ページを表示したいので、not_found というオーバーライド可能なメソッドを追加した
次は、メール送信とログ出力の予定
mod_perl とか fcgi はかなり後回し。ログイン画面を簡単に作る工夫とかもあると嬉しい。。。かな?
- Comments: 0
- TrackBacks: 0
フレームワーク (10) - 現状整理
少し間があいてしまったが、やっていないわけではなくて、Template-Toolkit 関連部分の実装を終えたので、現在試用しながら実装変更中
使っててわかったのが、
- config 関連の実装が必要
- YAML 形式のファイル読み込みにする予定
- Mail 送信関連の実装が必要
- トレンドは Email::* っぽいので、Email::Simple と Email::Send あたりを使ってみようかと思っている。でも、Email::* はお互い依存してそげなんで、後で考える。愛用してきた MIME::Lite でもいいんだが
。。。とか思ってたら、MIME::Lite も久しぶりにアップデートされてるじゃん!
First release from Perl Email Project. Updated packaging.
らしい。RJBS すげえ!
- Comments: 0
- TrackBacks: 0
フレームワーク (9) - DBIx::Simple::DeadObject
今日は DBIx::Simple 周り
DB 関連のエラー拾うために、よく
$dbh->select(...) or die $dbh->error;
とかするが、わざとエラーにしてみるために
$dbh->disconnect; $dbh->select(...) or die $dbh->error;
してみたら、
Database object no longer usable (because of ...)
と返ってきたので、さらに実験
use DBIx::Simple;
use Data::Dumper;
my $dbh = DBIx::Simple->connect('dbi:SQLite:dbname=dum.db');
print Dumper $dbh;
$dbh->disconnect;
print Dumper $dbh;
実行結果
$VAR1 = bless( {
'lc_columns' => 1,
'dbh' => bless( {}, 'DBI::db' ),
'dbd' => 'SQLite'
}, 'DBIx::Simple' );
$VAR1 = bless( {
'what' => 'Database object',
'cause' => 'DBIx::Simple=HASH(0x812c15c)->disconnect at db.pl line 7'
}, 'DBIx::Simple::DeadObject' );
おー、なるほど
if ( ref $dbh eq 'DBIx::Simple::DeadObject' ) {
print 'DB object has been already a-born.';
undef $dbh;
}
とかできるのね。使うことがあるかどうかはわからないけど
- Comments: 0
- TrackBacks: 0
フレームワーク (8) - サブクラスでのメソッドのオーバーライドを禁止する
C::M::App は、CGI::Application と同様、自分のクラスから継承されることを想定している
package MyClass; use basee 'CGI::Minimal::App'; 1;
んだが、一部メソッドは子クラスでのオーバーライド前提だし、一部メソッドはオーバーライドされたくないし、ということで、思案。他の言語みたいに attribute :final とか用意されてると
sub cannot_override :final {
}
とかするだけだし、そういうことを行うモジュール Attribute::Final もあるんだが、外部モジュール使うほどでもないし、attribute で実装しなくてもよかろう
# 子クラスの時だけ実行
unless ( ref $self eq __PACKAGE__ ) {
for my $method (@all_methods) {
next if .... ; # 親クラスのメソッドだったら何もしない
die 'You can NOT OVERRIDE method'
if ( grep {$_ eq $method} @not_override_methods );
}
}
まずは基本ということで、Class::Inspector 使ってみる
# Check methods that cannot override in Sub-Class
unless ( ref $self eq __PACKAGE__ ) {
my @not_override_methods = qw(
new run
_tt_obj _setup_http_headers _lvalue_method
);
for my $method ( @{Class::Inspector->methods(ref $self, 'expanded') || [[]]} ) {
next if $method->[1] eq __PACKAGE__;
die 'You can NOT OVERRIDE method ',__PACKAGE__,'::',$method->[2],' in ',$method->[1]
if ( grep {$_ eq $method->[2]} @not_override_methods );
}
}
続いて、Class::Inspector はコアモジュールではないので、使わない版
# Check methods that cannot override in Sub-Class
unless ( ref $self eq __PACKAGE__ ) {
my @not_override_methods = qw(
new run
_tt_obj _setup_http_headers _lvalue_method
);
{
no strict 'refs';
for my $method ( keys %{ref($self).'::'} ) {
next unless defined &{ref($self).'::'.$method};
die 'You can NOT OVERRIDE method ',__PACKAGE__,'::',$method,' in ',ref($self)
if ( grep {$_ eq $method} @not_override_methods );
}
}
}
タイムリーなことに、「どう書く?org」で「メソッド名一覧の表示」がお題になっているので、良さげな回答がでてきたらマネさせてもらおう
で、この実装だとコンストラクタ生成後にチェックするので、use した時点でチェクする方法考えた方がいいのかなぁ、とちょっと思った。new のしょっぱなにやっとけば同じかな
- Comments: 0
- TrackBacks: 0
フレームワーク (7) - lvalue で validation もしたい - その2 -
もっとスマートな実装方法はないものか
って、絶対あるはず。Class::Accessor::Lvalue とかあるんじゃね? と思ったら、やっぱりあった。速度比較とかしているこんなサイトも見つけた
楽々アクセサ生成だけならどれでもできそうだが、今回の要件を満たすかどうかはわからないので、後日勉強するということで。つうか、lvalue やめればシンプルになりますな
- Comments: 0
- TrackBacks: 0
Home > C::M::App Archive