Posted at 2006/08/05 00:55
in Programming|WebDev
今更blosxom? とか言われそうですが(笑)、久しぶりにいじってみました。テーマは「タグ化」。
blosxomは標準ではディレクトリ=カテゴリーなわけですが、はてなブックマーク等に慣れてくると、なにかと自由の利くタグを使いたくなってきます。タグ対応pluginは探せば既存でもいくつかあるようですが、やり方を思いついたので自分でも実装してみました。
ソースはこちら。
おおざっぱな仕組みは、filter()で
- エントリーファイルの1行目(タイトル行)からタグ([]で囲った文字列)を収集
- エントリーファイルの存在するパスもタグとして収集
- リクエストのパスをターゲットのタグとし、対象となるファイル以外をファイル一覧(%files)から削除
あとは通常のシーケンスでエントリーが表示されるので、story()で表示用のタグリンクを作成、というシンプルもの。
ただし、通常はカテゴリー(ディレクトリ)内のエントリー以外は表示をスキップする処理が走るので、blosxom.cgiを修正してカテゴリー機能自体を無効にする必要があります。
sub generate {
(中略)
# Only stories in the right hierarchy
# $path =~ /^$currentdir/ \
or $path_file eq "$datadir/$currentdir" \
or next; #←コメントアウト(実際は1行)
また、recentwritebacks_treeのような、エントリーファイルからタイトルを拾ってくるpluginは、タイトルからタグ部分を除去するように改造する必要があります。
sub gettitle {
(中略)
if($fh->open($file)) {
$ret = <$fh>;
$fh->close;
$ret =~ s!(\[[^]]+\])*!!g; #←追加
}
chomp($ret);
他にもタグリストのキャッシュ機能なんかも実装してありますが、細かい話なので省略。
この仕組みので面白いのは、エントリーファイルのパスも自動的にタグ扱いしてくれる点。つまり、既にカテゴリー分けされてる既存のエントリーは、何もしなくても最初から自動的にそのカテゴリー(ディレクトリ)名のタグが付いてくれます。
また、カテゴリーを2階層以上掘ってある場合、エントリーが属する上位のカテゴリーも全てタグとして付いてきます。例えば「/NetGame/RagnarokOnline/sample.txt」というエントリーの場合、「NetGame」と「RagnarokOnline」のタグが一気に付くわけです。「NetGame」直下に置けば「NetGame」だけに属し、「RagnarokOnline」の下に置けば「NetGame」「RagnarokOnline」両方に属する、つまり「RagnarokOnline」は「NetGame」をも含むという、タグ同士の包含関係のようなことが実現できるわけですね。
というわけで、かなり久しぶりにperlをいじりましたが……やっぱり自分で書くならrubyの方が好きだなあ(ぉぃ)。
Posted at 2006/08/04 23:32
in Programming
そういえば、今日(既に昨日)は
Binary 2.0カンファレンス
の日でしたか。どんな内容だったか気になるなあ……。
というわけで、せっかくなので(?)バイナリっぽいネタを少し。
諸事情で、以下のような機能を実現する必要があるとします:
printf()と同じフォーマットが使えるデバッグログ記録関数を作る。
ただし、vsprintf()は使えない。sprintf()は使える。
独自のログ書き出し関数log_puts()は、固定引数で文字列へのポインタを1つだけ受け付ける。
vsprintf()が使えれば一発で終了ですが、それが使えないとなるとどうしたものか。sprintf()が使えるのはいいけど、可変長で渡ってくる引数をどうやって渡せばいい?
(続きを読む)
Posted at 2006/08/04 23:32
in Programming
謎現象のデバッグ時や、挙動のよくわからないソースをおいかけている時など、どういう順番で関数が呼ばれているのがを可視化(ログ化)できればなーと思うことがよくあるのですが、ちょっとした方法を思いついたので試してみようかな……とおもったら、gccなら
-finstrument-functionsというオプションでそういう仕組みが実装可能
らしいです。流石gcc。
VCでもBoundCheckerを使えば可能らしいですけど。……そんなもん個人で買えるかっ。
ちなみに上で書いた「ちょっとした方法」というのは、「.o(.obj)のFixUp情報を書き換えて、関数コールの前後で指定関数を呼ぶproxyコードを呼ぶようにしてから、リンクする」という激しく力業な方法。gccやBoundCheckerも多分似たようなことをしているのでしょうけど(勘)、libbfdが使える環境なら自前でも楽勝で書けそう?
Posted at 2006/08/04 23:32
in Programming
一部で話題の
長文コメント
のあたりで触れられてる「
Javaの理論と実践: パフォーマンスに関する都市伝説を再検証する
」の記事。以前ブックマークしたまますっかり忘れてたので、いい機会なので読んでみました。
字義通りに受け取りすぎてしまう人いるみたいですけど、結論から言えば、速いケースは十分あるでしょうね。
記事ではメモリアロケーション処理について論じていますが、「malloc()でヒープメモリ確保」と「(最適化された結果)レジスタやスタックに割付け」を比較すれば、後者のほうが速いのは当然です。こういった差を積み重ねられれば、Cなどでべた書きするよりも、JavaなどのVM系環境の方が速くなる……というのが、動的最適化による高速化の思想でしょうか。
もちろん、最適化ゲインが動的最適化のための統計・分析コストを上回る範囲内にあることが前提です。逆に言えば、全コスト内で占める動的処理コストの割合が、ソフトウェアの巨大化と計算機パワーの増大によって相対的に低下したことで可能になった高速化手法であるとも言えるでしょう(機能ではなく、高速化のための動的化ってのは今まで考えたことなかったな……)。
もちろん、目的に比べて過剰な動的処理を行えば、当然最適化ゲインを食いつぶすだけで高速化にはなりませんし、とりうる挙動が限定されるシチュエーションでは、一般的・汎用的シチュエーション向けにチューニングされた最適化よりも、そのシチュエーションに特化した手作業の静的なコードの方がより効率的に動作するでしょう(静的処理の最後の砦?)。
初期のJavaなどは後者の悪い部分が目立っていたわけですが、計算機パワーの増大と最適化手法の進歩の相乗効果で、最近では前者に転んできたといったところでしょうか。
一方、現在でも後者のシチュエーションを積極的に利用してるのが、いわゆる「組み込み系」ですね。シチュエーションを限定すれば、現在の半導体技術の成果でより小型に、より広範囲にコンピューティングを提供することができるという「
イノベーション
」の一典型です。
この分野でも、ICチップと無線の融合という形で次のイノベーションが登場しつつありますけど。
Posted at 2006/08/04 23:32
in Programming
このへん
の話。やりかた思いついたので、VCでやってみました。ソースは
こちら
。VC6のコンソール環境で確認。
オリジナルとの違いは、define()の第4引数以降をまとめて括弧で囲む必要があること。これは、VC6は(あたりまえですが)C99対応しておらず可変長関数マクロが使えないので、第4引数以降を1つの引数として扱っているためです。これを関数本体の文字列にしているのが asprintf_like() ですが、別段言及するほど特別なことはしていません。
オリジナル同様、単なる力業ですねえ。