Ruby中bind / unbind方法的目的是什么?

使用Method#unbindUnboundMethod#bind的目的是什么?

从我收集的方法来看,方法是可调用的对象,如procs和lambdas,除了方法绑定到接收器的范围:

 class SomeClass def a_method; puts "from SomeClass"; end end s = SomeClass.new s.a_method # => "from SomeClass" 

如果我在SomeClass的上下文中或者如果我有SomeClass的对象,我可以调用a_method 。 我可以通过将方法提取为Method对象来使其成为可调用对象,但在此示例中它仍然绑定到SomeClass类的对象:

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

为什么我要从接收器unbind方法? 也许我可以传递它或bindbind到一个不同的对象,给它新的上下文,也许我可以有一个完全不同的对象调用这个方法没有inheritance,但我不能做任何事情,除非我把它绑定到它的对象原始类或我将其转换为Proc对象(实际上是一个lambda,因为方法和lambda有些相似):

 # 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" 

我可以将方法对象转换为proc,也许可以用它做一些事情:

 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" 

这样做的目的是什么? 这样的事情的真实世界应用是什么?

它确实对元编程很有用。 假设您想知道SomeClass#method的源代码的位置。 如果您可以生成SomeClass的实例,那么您可以在SomeClass实例上创建它的(绑定)方法实例,您可以在其上调用各种方法来调查方法的某些元数据。 但是,如果您不知道SomeClass#new的方法签名,或者如果SomeClass的构造方法被命名为SomeClass#new以外的怎么办? 只是安全地创建SomeClass的实例可能很困难。 这就是未绑定方法派上用场的地方。 在不打扰类的特定实例或者如何创建实例的情况下,您可以简单地执行SomeClass.instance_method(:a_method) (这是一种未绑定的方法),然后在其上调用source_location来调查定义的位置。

什么时候这种元编程在现实世界的应用中是必要的? 一个示例是在创建具有方法查找function的IDE时。