動的にメソッドを追加して動的に呼び出す
動的型付けの言語だと、動的にメソッドを追加するとかいうのができます。
Ruby
Module#define_methodで定義できます。
define_method("foo") { puts "fooo!" }
動的に呼び出すときはObject#send(メソッド名, 引数)呼び出せますが、privateなメンバーやメソッドであろうが容赦なく呼び出せるので要注意*1。
JavaScript
プロトタイプベースの言語なので息を吸うようにできます。でないと困りますよね。
var obj = {}; obj.foo = function() { console.log("foooo!"); };
JavaScriptでプロパティやメソッドを動的に呼び出すときはこうします。
document["getElementById"]
騙されたと思ってF12を押してコンソールを開き、おもむろに打ち込んでみましょう。
PHP
PHP5.3からできるようになりました。5.4だとトレイトを使うと良さげですが。
class Foo { protected $methods = []; public function __set($name, $value) { if (is_callable($value)) { $this->methods[$name] = $value->bindTo($this); } } public function __call($name, $args) { if (is_callable($this->methods[$name])) { return call_user_func_array($this->methods[$name], $args); } } } $foo = new Foo; $foo->bar = function($baz) { $this->baz = $baz; }; $foo->bar('Hello'); echo $foo->baz . PHP_EOL; //Hello
呼び出すメソッドを変えるには次のようにするらしいです。
function foo1() { } function foo2() { } $c = "foo"; $c1 = $c."1"; $c2 = $c."2"; $c1(); //call foo1 $c2(); //call foo2
これはもっと早く知っておきたかった…
*1:privateメソッドのテストをするときなんかは逆に好都合かもしれませんね。