2016-01-17 11 views
6

Method#unbindUnboundMethod#bindの目的は何ですか?Rubyのbind/unbindメソッドの目的は何ですか?

私が集まる何から、メソッドは、メソッドは、その受信機の範囲にバインドされていることを除いて、procsのとラムダのような呼び出し可能オブジェクトです:

class SomeClass 
    def a_method; puts "from SomeClass"; end 
end 

s = SomeClass.new 
s.a_method # => "from SomeClass" 

私はSomeClassのコンテキスト内だ場合、私はa_methodを呼び出すことができますまたはSomeClassのオブジェクトがある場合。私はMethodオブジェクトとしてメソッドを抽出して、それ呼び出し可能オブジェクトにすることができ、まだそれはまだ、この例では、クラスSomeClassのオブジェクトにバインドされています:

m = s.method :a_method 
m.class # => Method 
m.owner # => SomeClass 
m.call # => "from SomeClass" 

は、私がその受信機からメソッドをunbindしたいと思うのはなぜ?たぶん私はこれを渡すことができますかbindそれを新しいコンテキストを与える別のオブジェクトに渡すことができます、多分私は完全に異なるオブジェクトを継承なしでこのメソッドを呼び出すことができますが、元のクラスまたはI Procオブジェクト(実際にラムダ、メソッドとラムダはやや類似しているため)に変換します。私はprocのにメソッドオブジェクトを変換し、多分それで何かを行うことができ

# Module#instance_method gives me an UnboundMethod 
ub = SomeClass.instance_method :a_method 
ub.class # -> UnboundMethod 

# now I can't make any calls 
ub.call # -> NoMethod Error, undefined method 'call' 

class AnotherClass; end 
a = AnotherClass.new 
b = ub.bind(a) # -> TypeError: bind argument must be an instance of SomeClass 
b = ub.bind(SomeClass.new).call # -> "from SomeClass" 

AnotherClass.class_eval do 
    # I can access m becausec this block is evaluated in the same 
    # scope it's defined, so I can grab m ;) 
    define_method(:method_from_some_class, m.to_proc) 
end 

AnotherClass.instance_methods(false) # -> [:method_from_some_class] 
a.method_from_some_class # -> "from SomeClass" 

これを行う目的は何ですか?このようなことのための実際のアプリケーションは何ですか?

+0

Welp ... http://stackoverflow.com/questions/33708250/what-is-the-point-of-rubys-method-unbinding-mechanism – ndn

+1

私は彼らのことを理解していますが、 8年のルビープログラミングでは、時折反射的なメタプログラミングの巧みさを含めて、私はバインドされていないメソッドで 'bind'を使う必要はなかったし、まったくバインドされていないメソッドで多くを行ったことがありません。彼らはめったに必要ありません。しかし、彼らがルビーの完全な反射制御のためにそこにいるのは良いことです。あなたがそれらのための使用を見ていない場合、あなたが1つ持っているときに知っているだろうトリッキーなもののために使用がまれであるためです。それがあなたの日々のツールボックスの一部なら、あなたはおそらくあまりにも賢い方法です。 – jrochkind

答えて

6

本当にメタプログラミングに役立ちます。 SomeClass#methodのソースコードの場所を知りたいとします。 SomeClassのインスタンスを生成できる場合は、そのSomeClassインスタンスに(バインドされた)メソッドインスタンスを作成できます。このインスタンスでは、メソッドのいくつかのメタデータを調査するさまざまなメソッドを呼び出すことができます。しかし、SomeClass#newのメソッドシグネチャがわからない場合、または以外のSomeClassのコンストラクタメソッドの名前が付けられた場合はどうなりますか? SomeClassのインスタンスを安全に作成するのは難しい場合があります。それが非結合メソッドが便利なところです。クラスの特定のインスタンスやインスタンスの作成方法を気にすることなく、SomeClass.instance_method(:a_method)(バインドされていないメソッド)を呼び出してから、source_locationを呼び出して定義の場所を調べることができます。

実際のアプリケーションでこの種のメタプログラミングが必要なのはいつですか? 1つの例は、メソッドルックアップのための関数を持つIDEを作成するときです。

関連する問題