中島@ブレーンです。

> と思ったんですけど、mod_perl風だと、
> 
> --- foo.rb ---
> module Foo
>   def handler(r)
>     r.content_type = "text/plain"
>     r.send_http_header
>     r.print("hello world")
>   end
> end
> --------------

コンテンツハンドラだけを書くならば、できることはたいして違いはないのです
が、こっちの方がずっとかっこいいですね。特に、私のやり方ではハンドラの中
からapacheのAPIを呼ぼうとすると、

    print $stdout.escape_html(l)

などとすることになって、なんで$stdoutがそんなmethod持ってんのじゃ!という
違和感が残ります。

> RubyRequire foo
> <Directory "/home/httpd/cgi-bin/ruby">
>   SetHandler ruby-script
>   RubyHandler Foo
> </Directory>
> 
> みたいな形になるんですね。
> 
> どっちがいいかなあ。
> もうちょっと考えます。
> # 他の案も歓迎します。

欲を言えば、コンテンツハンドラだけでなく他のハンドラも呼べるようなAPIに
なっていて欲しいです。実は最初に私が作ろうと思ったのは次のような方法です。

RubyRequire foo
RubyHandlerObject 'FooHandler.new'
# または RubyHandlerClass FooHandler

<Directory "/home/httpd/cgi-bin/hoge">
   SetHandler ruby-script
   RubyHandlerObject 'HogeHandler.new'
</Directory>

<Directory "/home/httpd/cgi-bin/fuga">
   SetHandler ruby-script
   RubyHandlerObject 'FugaHandler.new'
</Directory>

で mod_rubyからは次のような処理をするわけです。

1) RubyHandlerObjectで生成されたObject(ハンドラーオブジェクト)を保持しておく
2) 各ハンドラーオブジェクトに対して、resopond_to?(:child_init)や
   respond_to?(:uri_trans)のような問合せを行ない、ハンドラーオジェクトに
   定義されているメソッドを調べておく
3) mod_rubyにはコンテンツハンドラだけでなく全てのハンドラを定義しておき、
   全てのフックにおいて、各ハンドラーオブジェクトのフック(のうち定義され
   ているものを呼ぶ
4) ハンドラーオブジェクトの返す値によって、次のハンドラーオブジェクト
   (のフックメソッド)を呼ぶかどうか決める(OK か DECLINE か)
5) 最後のハンドラーオブジェクトの返した値が、mod_rubyのハンドラーの返却値
   になる。

上記の例では、/cgi-bin/hoge/*に対するアクセスはまず
HogeHandler::handlerで処理され、これがDECLINEを返すとさらに
FooHandler::handlerでも処理されるという感じです。

必要に応じてコンテンツハンドラだけでなく、認証やアクセス制御などにも介入
できるし、各フェーズ間のデータの受渡しもmod_perlよりずっときれいに処理で
きると思います。

特に、RWikiサーバのように他のプロセスと連携しながら処理をすることを考え
ると、child_initの(apacheがforkした直後に呼ばれる)フックがあるといいと思
います(その中で他のプロセスに接続しておく)。

とまあ、こんなことを考えたのですが、apacheもrubyも知らないでこれを作るの
は無理だろうと思って、とりあえず手抜きの方法でやってみたというわけです。

--
中島 拓 (tnaka / brain-tokyo.com)
http://www03.u-page.so-net.ne.jp/dc4/tnaka/