三日ぶりの娑婆の空気はうまい。飯食って本屋行って、歩いて帰ってきました。本屋でSTUDIO VOICEを読んでたら気になってしまい、「臨死!江古田ちゃん」を買ってしまいましたよ
2006年09月
TT + DateTime のアレ
DateTime MLに来てたのでデバッグしてみた。Template::Stash の該当部分が
my $atroot = ($root eq $self);
となっており、同じ部分をTemplate::Stash::XSで探すと
atroot = sv_derived_from(root, TT_STASH_PKG);
となってることから、Template::Stashを
my $atroot = eval { $root->isa(__PACKAGE__) };
に変えたら直ったですよ。
追記:sub _dotop内です。もう一カ所同等の処理をしている箇所もあるんだけど、そこは変更の必要ないっぽい。
書いとく
ワードリスト
http://clouder.jp/yoshiki/mt/archives/000712.html
http://b.hatena.ne.jp/entry/http://clouder.jp/yoshiki/mt/archives/000712.html
俺もqw()。俺も直す。qw//だと正規表現だかなんだかわかんねー。
のわ
なんか日記消しちゃった。
風邪風邪風邪
今日は一日寝てた。うつらうつらして大汗をかいたあと、むくりと起き上がってコーディング。また気絶してうつらうつらして、大汗をかいて・・・の繰り返し。まだ微妙に熱もあるっぽいし、治るのにはまだもうちょいかかりそう。
Catalyst + Japanese Charsets
俺は文字コード関連に関しては正直「面倒くさい」ということ以外たいしてしらないのだが、JcodeとUnicode::Japaneseの根本的な差ってなんなんだろう?今のところCatalystで入ってきた文字列とかをUTF8に変換するのにJcodeを使っていたのだが、なんか「ペンギン」は文字化けしないのに「ペン」だと文字化けする現象に遭遇。よくわからんかったのでとりあえず他の書き方も試してみたらUnicode::Japaneseは動く、ということに気がついた。
じゃあ、と思ってこれを書いてみたんだけど、
use strict;
use Encode;
use Unicode::Japanese;
use Jcode;
my @words = qw(ペンギン ペン);
foreach my $w (@words) {
my $jcode_utf8 = Jcode->new($w)->utf8;
my $uj_utf8 = Unicode::Japanese->new($w)->utf8;
print "jcode is_utf8 ? ", Encode::is_utf8($jcode_utf8) ? "Y" : "N", "\n";
print "uj is_utf8 ? ", Encode::is_utf8($uj_utf8) ? "Y" : "N", "\n";
print "jcode eq uj ? ", $jcode_utf8 eq $uj_utf8 ? "Y" : "N", "\n";
print "jcode as hex = ", (map { my $p = unpack("H2", $_); "\\x$p" } ($jcode_utf8 =~ /(.)/g)), "\n";
print "uj as hex = ", (map { my $p = unpack("H2", $_); "\\x$p" } ($uj_utf8 =~ /(.)/g)), "\n";
print Unicode::Japanese->new($jcode_utf8)->euc, "\n";
print Jcode->new($uj_utf8)->euc, "\n";
}
結果はこんな感じ:
jcode is_utf8 ? N
uj is_utf8 ? N
jcode eq uj ? N
jcode as hex = \xe3\x83\x9a\xe3\x83\xb3\xe3\x82\xae\xe3\x83\xb3
uj as hex = \xa5\xda\xa5\xf3\xa5\xae\xa5\xf3
ペンギン
ペンギン
jcode is_utf8 ? N
uj is_utf8 ? N
jcode eq uj ? N
jcode as hex = \xe3\x83\x9a\xe3\x83\xb3
uj as hex = \xa5\xda\xa5\xf3
ペン
ペン
うーんうーん。別にどっちがどっちでもいいんだけど、この二つのモジュールはそもそも何が違うの?入力文字列が基本的にUTF-8、出力もUTF-8で、途中正規化やらなんやらで変換をかましたい時はどっちのモジュールを使う方がいいのだろう?
株
とある株の新規上場の抽選にあたった。残念ながらたかだか100株なんだが、まぁいいか。この新規上場株を購入するにあたって、今まで持ってた電鉄株を売った(とは言ってもさっき売り注文を出したから今の段階では未成立なんだが)ので、そのお金でもっと買えるからざっくり買うかー。
風邪ひいた
downloader.cgiっつーの作った。焼き魚定食のお昼を食べた。気がついたら喉が痛かった。データベースをいじって某社のずさんなデータをまた一つ浮き彫りに。ミーティングするも機嫌悪。Catalyst とテンプレートの使い方をざっくり説明。体力の限界。銀座アスターの弁当を買って、帰宅。寝る。起きる。
メーリングリストを作成するのにmailmanをインストール、設定。svnnotifyを設定。
ちなみに風邪は昨日の夜、飲んで帰ってきてその後床で作業してたら窓を全開であけっぱなしにしていつのまにか気絶するように寝てしまい、気がついたら風邪ですよ。アホだ。
「不信の時」の最終回ひどい
なんだ、あれだけドロドロの話やっておいて最後はキレイにまとめるのかよ。しかも石黒賢、いつのまにか死んでるしw
腹減ったよ。
9時起床。ちょっと遅かった。ずっと作業。jcode.plなんて過去の遺物を使ってみる。腹減った腹減った。
diff と patch
実はこれだけ色々と開発の事に関して書いてきても、いまだに結構中途半端な知識しかないのだが、別にたいした事じゃないけど一発でできてみるとすごい嬉しい事がたまにあったりする。で、今日のはこれ:
Hogeというディレクトリがsubversion管理下にないことを忘れたまま作業してしまい、一旦作業したディレクトリをmvして、そこに新しくsvn co したものを持ってきた:
mv Hoge Hoge.old
svn co http://hoge.com/Hoge/trunk Hoge
で、もちろんHoge.oldの変更は残したいのでパッチを当てたりしたいわけなんだが、ここでだいたいいつもどうしようかと悩んでからとりあえずhoge.patchとかにdiffを落とすわけだが、なんかしらんけど今日はひとつのコマンドでやりたかったのでちょっとやってみた:
cd Hoge
diff -du -r . ../Hoge.old | patch -p0
一発で全部のパッチがあたった!俺すげぇ!いや、くだらないのはわかってるけど。俺すげぇ!
DBIx::Classページングのドツボ
わかった! $rs->search() をつなげて検索をかけていたのだが、これで最初のsearch()だけでpageとrowsを指定していたにもかかわらず、searchの実装として以下のようになっているため、offsetがどんどん増えて行ってしまう:
my $rs = DBIx::Class::Resultset->new(..., { page => $p, rows => $r });
# この時点で、$rs->{attrs}{page}, $rs->{attrs}{rows}を元に$rs->{attrs}{offset}
# が$p と $rを元にして計算される
# 条件1で検索
$rs = $rs->search( ... ); # ここでD::C::ResultSet->new がまた呼ばれる
# 条件2で検索
$rs = $rs->search( ... ); # さらにもう一回newが呼ばれる
ポイントはそれぞれのsearchの呼び出しの時にnewが呼ばれて、offsetが更新される事。つまり
offset += row * (page - 1);
として毎回計算されるわけだ。でもrowとpageは毎回同じものがコンストラクタに渡されるから、searchの度にoffsetが足される。そりゃあページングもずれます。
というわけで、教訓:ページングは一番最後に指定!
my $rs = $schema->resultset('Hoge');
$rs = $rs->search( \%where1 );
$rs = $rs->search( \%where2 );
$rs = $rs->search( \%where3 );
# で、最後に
$rs = $rs->search( undef, { rows => $rows, page => $page });
DBIx::Classのページング
なんか変だ・・・Catalystから使ってるのだが、
$c->model('DBIC')->resultset('Hoge')->search(
undef,
{ page => 2, rows => 10 }
);
みたいな事してる時になぜか2ページ目がでない・・・んんん、なんだこれ・・・ページはたしかに2ページ目なんだけど・・・おかしい・・・
追記!不思議な事が起こってるよ!
page => 6, rows => 5でやってみると、DBIx::Class::ResultSet->{attrs}の中身を見るとoffset = 25って書いてあるのに、DBIx::Class::Storage::DBIの中の_sql_makerが作ったSQLの内容を見るとOFFSETが75になってるよ!おかしい!おかしい!
ってところで俺は今日はもうリタイヤ!
出歩きますよ。
夕飯はリンガーハット。ずるずる。うまいけどまずい。
家に帰っても別に楽しい事はないのでまたぞろほっつき歩くわけですよ。今日は軽く終えようとは思ってますが、まぁ例によってスコッチ飲んできます。
プロジェクトのモジュール=49個
自分の感覚でプロジェクト進行率65%で、ただいまのプロジェクトのモジュール49個、18スクリプト、58テンプレート、308コミット。49個というのはCatalystのControllerの分も入ってるのでまぁ12、3個があちこちのURLのハンドリングをしたりしてるわけだが。モジュール類はコメントも含めて5875行、スクリプト類は1585行、テンプレートは1378行。
Catalyst や DBIx::Classを使ってるので相当コードの量も省略できてるわけだが、これだけの行数でも結構な事できるようになった。コミットログを見ると、まともに作業が始まってちょうど1月。これだけの量のコード、これだけの情報でよく書いたと思うよ、本当。
数十万行のプロジェクトってザラだけど、Perlで書いている限り俺の経験ではよっぽど大掛かりなものでもだいたい1万行~3万行で終わらなければなにか間違った事をしてると思う。実際作業の10%くらいはコードのリファクタリングで、例えばControllerの部分のリファクタリングだけで500行近くは100行ほどのモジュールを一個足すだけで消してると思われ。
うどん
新宿の麺通団でうどん。かまたまの小とめんたいしょうゆの小。うまうま。そのままとんぼ帰りで渋谷。仕事。
バルブレア 15年
ブランカメンタのソーダ割り、マティーニ、UDのポートエレンカスクストレングス。〆はバルブレアの15年もの。これもカスク。最近モルトはハーフで飲んでる。量的にはこれくらいがいい感じになってきた。別にがんばってショットを飲む必要もなくなってきたなぁ。
沖縄料理
馬場のちゃんぷる亭で食事。定食とかのほうがメインな感じがするけど一品料理もある。ひとつだけ定食を頼んであとは一品をあれやこれや。豚肉とメンマの炒め物の定食を頼んだのだが、これがバカうま。海藻入りのご飯と合う事合う事。うめぇ。
その後店を変えて、あんまよくなかったので解散。最後に飲んだジントニックがひどかったので口直しに新宿に移動してちゃんとしたジントニック。最後にスプリングバンク68年ものとボウモアの68年ものをそれぞれハーフで飲み比べ。うますぎる。
1弦も購入。やっとスーパーマリオ弾ける。
3連休
3連休ってなんですか?仕事が入りました。あはは。