dRubyでmethod_missing
メソッドの可視性の実現方法を修正して、method_missingを使うオブジェクトを リモートから利用できるようにしました。
メソッドの可視性
というか呼び出し制限について、dRubyではpublicなメソッドのみを呼び出せるようにしています。 従来は、respond_to?を用いて検査していたのですが、privateでもprotectedでもない、という 検査に変更しました。
この変更により定義されていないpublicなメソッド(一般にmethod_missingを使ったトリックで実現される)を 呼び出すことができるようになります。
method_missingの例
mm.rb / server
未知のメッセージを受け取ると、それを文字列にして返すサーバです。 役には立ちませんが実験には十分です。
require 'drb/drb' class Foo def method_missing(msg, *arg, &block) 'method_missing: ' + msg.to_s end end DRb.start_service(nil, Foo.new) puts DRb.uri DRb.thread.join
mmc.rb / client
mm.rbを呼び出すスクリプトです。 hello_world, druby_book_2などのメソッドを呼び出します。 またprivate methodであるevalを呼び出してエラーになることを確認します。
require 'drb/drb' uri = ARGV.shift DRb.start_service mm = DRbObject.new_with_uri(uri) p mm.hello_world p mm.druby_book_2 begin p mm.eval('error') rescue p $! end
実験
まあ、こんなのです。
[ターミナル1] % ruby mm.rb druby://four.local:51758 [ターミナル2] % ruby mmc.rb druby://four.local:51758 "method_missing: hello_world" "method_missing: druby_book_2" #<NoMethodError: private method `eval' called for #<Foo:0x353c3c>:Foo>
Link
RedHandedにて、Coolなmethod_missingに関する議論がなされています。