メソッドを動的に呼び出したい

CamlinternalOOを眺めていて、文字列からメソッドを得る関数が定義されていることに気づいた。これを使えば、文字列でメソッド名を与えてメソッド呼び出しを行う関数が書けるのではないだろうか。

ためしに簡単な例でやってみた。

# let invoke obj f =
    let tag = CamlinternalOO.public_method_label f in
      Obj.magic (CamlinternalOO.send (Obj.magic obj) tag);;
val invoke : 'a -> string -> 'b = <fun>

これがメソッド名を文字列で与えて呼ぶための関数。

使い方はこう。

# let obj = object method f x = x + 1 end;;
val obj : < f : int -> int > = <obj>

# let a : int = invoke obj "f" 3;;
Warning X: this argument will not be used by the function.
val a : int = 4

ちゃんと3+1が帰ってきているのがわかる。 a : intがないとval a : 'a = となってしまうのでいまいち。

もちろん、間違ったメソッド名を与えると落ちる。

# let g : string = invoke obj "g" "a";;
Warning X: this argument will not be used by the function.
$                 ←シェルに戻った

次回はオブジェクト作成編。