トップ «前の日記(03/03/2010) 最新 次の日記(03/06/2010)» 編集

本 日 の h o g e

hogeとはワイルドカードのようなものです。日々起こった、さまざまなこと −すなわちワイルドカード− を取り上げて日記を書く、という意味で名付けたのかというとそうでもありません。適当に決めたらこんな理由が浮かんできました。

更新情報の取得には rdflirs を使ってもらえると嬉しいです.


03/05/2010 ふむ [長年日記]

tDiary 2689日目

[golang] リフレクション

先日の Go の記事 で取り扱おうかどうしようかと最後まで悩んだ末に除外したリフレクション.

先日所用にて適当な HTTP サーバを Python でさっと書いたのだけれど,さて Go でこういったものを書くとどうなるだろうと思い,書いてみたらリフレクションの良い (かどうかは分からないけれど) 例になりそうだったので紹介してみようかなと思い筆をとった次第.

これ がソースコード. Python の BaseHTTPServer 相当とするために reflect を使っていて,ビルトインの http を wrap する形で実装した. 効率はあまりよろしくないけれど,まあシビアな用途でこんなの使わないので充分でしょう. ちなみに Makefile は x86 と x86_64 にしか対応してないのであしからず :-)

handler.Handle() はあるオブジェクトから do<METHOD> という名前のメソッドを走査して,マッチしたらそのメソッドを http.Conn と http.Request と共に呼び出す. 「あるオブジェクトを調べて,ある名前を持つメソッドを抽出して呼び出す」,これを行うために,reflect.Typeof() で得た型情報からメソッドの名前を,reflect.NewValue() で得た値情報からメソッドそのものをそれぞれ得ている.

main からは CCHandler が渡されているので,CCHandler に実装された doGET() と doHEAD() がリクエストに応じてよしなに呼び出されるという案配. 例えば HOGE とかいうリクエストメソッドを作りたければ doHOGE() を実装するだけ.

実は reflect.Typeof() で得た型情報からもメソッドそのものを得ることは可能なのだけれど,型情報から得たものは特定のレシーバにバインドされていないので,こちらを利用する場合,Call() 引数にレシーバとしてオブジェクトを渡してやる必要があったりする. ここら辺は Python に慣れ親しんだ人には違和感ないと思うのだけれど,Python を触ったことのない人には「は?」という感じかも知れない.

ちなみに CCHandler の CC はチョメチョメの略です.