加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Ruby的方法解绑机制有什么意义?

发布时间:2020-12-17 01:19:34 所属栏目:百科 来源:网络整理
导读:Method#unbind 返回对该方法的UnboundMethod引用,该引用稍后可以使用 UnboundMethod#bind 绑定到另一个对象. class Foo attr_reader :baz def initialize(baz) @baz = baz endendclass Bar def initialize(baz) @baz = baz endendf = Foo.new(:test1)g = Foo
Method#unbind返回对该方法的UnboundMethod引用,该引用稍后可以使用 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()类似.但是,要将方法绑定到的对象必须属于同一个类.

我能想到的唯一应用是,如果解除绑定方法,丢失原始实现(重新定义原始或单例类中的方法),然后重新绑定并调用它.

解决方法

我将总结迄今为止我发现的好用途.虽然没有使用unbind.

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

假设你想做这样的事情:

class Foo
  alias old_bar bar

  def bar
    old_bar
    some_additional_processing
  end
end

这将有效,但会留下old_bar,这不是一个可取的东西.相反,人们可以这样做:

class Foo
  old_bar = instance_method(:bar)

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

其次,从层次结构中调用方法的另一个实现. Source.

帖子中给出的非常实用的例子是,在调试过程中,您经常需要找到定义方法的位置.一般来说,你可以这样做:

method(:foo).source_location

但是,如果当前实例实现了方法方法,这将无法工作,就像ActionDispatch::Request的情况一样.在这种情况下,您可以执行以下操作:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读