`respond_to?` 与 `respond_to_missing?`

Posted

技术标签:

【中文标题】`respond_to?` 与 `respond_to_missing?`【英文标题】:`respond_to?` vs. `respond_to_missing?` 【发布时间】:2012-11-27 09:36:54 【问题描述】:

定义respond_to_missing? 而不是定义respond_to? 有什么意义?如果为某个类重新定义 respond_to? 会出现什么问题?

【问题讨论】:

【参考方案1】:

没有定义respond_to_missing?,尝试通过method获取方法会失败:

class Foo
  def method_missing name, *args
    p args
  end

  def respond_to? name, include_private = false
    true
  end
end

f = Foo.new
f.bar  #=> []
f.respond_to? :bar  #=> true
f.method :bar  # NameError: undefined method `bar' for class `Foo'

class Foo
  def respond_to? *args; super; end  # “Reverting” previous redefinition

  def respond_to_missing? *args
    true
  end
end

f.method :bar  #=> #<Method: Foo#bar>

Marc-André(Ruby 核心提交者)有一个很好的blog post on respond_to_missing?

【讨论】:

出于兴趣,respond_to? 有什么用。它有合法的用例吗? @BrendonMuir 重新定义它?从来没有,真的。但是respond_to? 应该始终是被调用的方法。你不应该直接打电话给respond_to_missing? 是的,对不起,我就是这个意思 :) 很高兴知道 :) 在我看来 respond_to_missing? 不应该默认返回 true。相反,它应该类似于 check_if_method_meet_condition || super 。另一件事是它通常被定义为respond_to_missing(method_name, include_private = false) @PiotrGalas 如果method_missing 存在(并且从不引发NameError 本身),那么respond_to_missing? 返回true 总是很有意义。但这只是一个人为的例子。至于后一点:我是懒惰的,这里从来没有使用过参数。【参考方案2】:

如果您要覆盖 method_missing,最好创建 respond_to_missing?。这样,即使没有显式声明,该类也会告诉您所调用的方法存在。

respond_to?可能不应该被覆盖:)

【讨论】:

以上是关于`respond_to?` 与 `respond_to_missing?`的主要内容,如果未能解决你的问题,请参考以下文章

添加respond_to时的ActionController::UnknownFormat

ruby object.respond_to?( “每个”)

Rails 5 API 控制器中未定义的实例方法“respond_to”

JavaScript 使jQuery respond_to:js

Rails:respond_to 块是如何工作的?

respond_to 的 Ruby 细化问题?和范围