Ruby的方法解除绑定机制有什么意义? [英] What is the point of Ruby's method unbinding mechanism?

查看:82
本文介绍了Ruby的方法解除绑定机制有什么意义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Method#unbind 返回一个UnboundMethod对方法的引用,以后可以使用 UnboundMethod#bind .

Method#unbind returns an UnboundMethod reference to the method, which can later be bound to another object using UnboundMethod#bind.

class Foo
  attr_reader :baz

  def initialize(baz)
    @baz = baz
  end
end

class Bar
  def initialize(baz)
    @baz = baz
  end
end

f = Foo.new(:test1)
g = Foo.new(:test2)
h = Bar.new(:test3)
f.method(:baz).unbind.bind(g).call # => :test2
f.method(:baz).unbind.bind(h).call # => TypeError: bind argument must be an instance of Foo

最初,我认为这非常棒,因为我希望它的工作方式与JavaScript的Function.prototype.call()/Function.prototype.apply()类似.但是,您要绑定方法的对象必须属于同一类.

Initially, I thought this is incredibly awesome, because I expected it would work similarly to JavaScript's Function.prototype.call()/Function.prototype.apply(). However, the object to which you want to bind the method must be of the same class.

我唯一想到的应用程序是:取消绑定方法,丢失原始实现(在原始类或单例类中重新定义该方法),然后重新绑定并调用它.

The only application I can think of is if you unbind a method, lose the original implementation (redefine the method in the original or singleton class) and then rebind and call it.

推荐答案

我将总结到目前为止所发现的良好用途.都不使用unbind.

I'll summarize the good uses I found so far. Neither uses unbind though.

首先,使用旧的实现覆盖方法. 来源,感谢@WandMaker.

Firstly, overwriting a method, using the old implementation. Source, thanks to @WandMaker.

假设您要执行以下操作:

Let say you want to do something like this:

class Foo
  alias old_bar bar

  def bar
    old_bar
    some_additional_processing
  end
end

这将起作用,但会留下old_bar,这是不希望的.相反,可以这样做:

This will work, but will leave behind old_bar, which is not something desirable. Instead, one could do:

class Foo
  old_bar = instance_method(:bar)

  define_method(:bar) do
    old_bar.bind(self).call
    some_additional_processing
  end
end


其次,从层次结构中调用方法的另一种实现. 帖子中给出的一个非常实际的示例是,在调试过程中,您经常想找到定义方法的位置.一般来说,您可以通过以下方式做到这一点:

The very practical example given in the post was that often times during debugging, you want to find where a method was defined. Generally speaking you can do that by:

method(:foo).source_location

但是,如果当前实例实现method方法,则此方法将无效,例如 ActionDispatch::Request .在这种情况下,您可以执行以下操作:

However, this won't work if the current instance implements a method method, like is the case with ActionDispatch::Request. In that case you can do:

Kernel.instance_method(:method).bind(self).call(:foo).source_location

这篇关于Ruby的方法解除绑定机制有什么意义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆