【问题标题】:Can I monkey patch NilClass to return nil for missing methods?我可以修补 NilClass 来为缺少的方法返回 nil 吗?
【发布时间】:2012-03-17 03:50:20
【问题描述】:

在其他语言中,例如(例如,objective-c)在 nil 对象上调用方法会静默失败并返回 nil,但在 ruby​​ 中会出现这样的错误...

undefined method `some_method' for nil:NilClass

这(对我而言)会产生如下代码:

if some_object && some_object.cool?  # instead of if some_object.cool?
  # do some cool stuff
end

或

some_object.do_awsome_thing if some_object

这一切看起来都是倒退和奇怪的。

两个问题

  1. 我做错了什么,处理可能出现 nil 对象的正确方法是什么

  2. 如果我只是猴子修补 nil 对象以返回 nil for missing_methods,会发生什么样的可怕可怕的事情?

IE:

class NilClass
  def missing_method
    nil
  end
end

【问题讨论】:

  • 迁移到其他堆栈交换站点?
  • 不,这可能因为过于主观而被票数接近(即没有确定的、客观的答案,导致难以直接回答,并可能引发广泛的辩论)。
  • 这是一个非常自以为是的问题,但它不经常发生的原因是因为失败是好的。查看Failing Fast
  • 我想我问这个问题的原因之一是我对 ruby​​ 很陌生,我没有意识到这可能是一个固执己见的问题..

标签: ruby null


【解决方案1】:

这是一种设计选择,我想nil 可以用nil 响应它不知道的方法。

为了保持一致,你应该定义respond_to_missing?:

class NilObj
  def method_missing(*_)
    nil
  end
  def respond_to_missing?(*_)
    true
  end
end

如果你按照你的建议做了猴子补丁method_missing,特别是如果你也相应地重新定义了respond_to_missing?,你可能会得到一些奇怪的副作用,因为鸭子打字需要一些内省,这通常是通过检查对象是否响应来完成的除了特定的类。

例如,nil 会响应 to_ary 的事实似乎表明它是“类数组”,但事实并非如此。

一些内置方法会调用respond_to?,还有一些会简单地调用和救援NoMethodError,所以即使没有respond_to_missing?,你也会得到一些奇怪的副作用。

【讨论】:

  • 其实respond_to?会检查类层次结构中实际定义的方法,不会触发method_missing,所以nil.respond_to? :foo还是会返回false。
  • @coreyward:扩展了我的回答,指出一些核心方法只是继续调用方法而不依赖于respond_to?。
  • @coreyward 参见文档Object#respond_to_missing?
  • 罗杰。我以前没玩过。
【解决方案2】:

如需比我写的更全面的答案,请阅读 Reg Braithwaite 的 The Hopelessly Egocentric Blog Post

简短回答:有些人认为你的 method_missing 技巧的行为是可取的,但也有陷阱。 Ruby 的设计者认为默认情况下这种行为是不合适的。其他语言设计者选择其他语言(例如:Objective-C)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    • 2012-11-24
    相关资源
    最近更新 更多