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

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

【问题讨论】:

    标签: ruby metaprogramming


    【解决方案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?可能不应该被覆盖:)

    【讨论】:

      猜你喜欢
      • 2014-01-10
      • 1970-01-01
      • 1970-01-01
      • 2016-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-21
      相关资源
      最近更新 更多