猴子修补 Object 以更自然的方式测试元素是否在数组中是不是一个坏主意?

Is it a bad idea to monkey patch Object to have a more natural way for testing if an element is in an array?

我们可以在 Ruby 中测试数组(或另一个 Enumerable)是否包含具有 include? 方法的值...

puts %w(one two three four).include?("two")
# => true
puts %w(one two three four).include?("five")
# => false

...但不直接测试一个值是否包含在数组中(语义相同,但不是语言的一部分)...

puts "two".in?( %w(one two three four) )
puts "five".in?( %w(one two three four) )

我考虑过猴子补丁 Object 有一个方便的 Object#in? 方法,类似于:

class Object
  def in?(array)
    return false unless array.respond_to?(:include?)  # Or perhaps raise an error.
    return array.include?(self)
  end
end

使用 Object 上的方法定义,

"two".in?( %w(one two three four) )
# => true
:nuts.in?( [:banana, :chocolate, :pie] )
# => false

工作得很好,非常接近表达该测试的正常句子。

通常,我 运行 认为 if element.in?(array) 是一个比 if array.include?(element) 更自然的表达方式,尤其是当数组作为文字(而不是变量引用)包含时。

问题(同时忽略了对猴子补丁的普遍看法):这个猴子补丁的例子是一件聪明的事吗?有一个 Object#in? 方法的具体缺点是什么,又没有进入猴子修补对象的一般利弊(在 Ruby 中)?

我要么需要适当的 Rails 主动支持模块(core_ext/object/inclusion.rb) into your project, or if you are going to modify Object yourself, use the same source code as Rails' Object#in? 方法。

# File activesupport/lib/active_support/core_ext/object/inclusion.rb, line 12
def in?(another_object)
  another_object.include?(self)
rescue NoMethodError
  raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
end

忽略 Ruby 中的一般论点 for/against 猴子补丁,您描述的代码是 方便方法 的示例,可帮助您提高可读性。反对将其包含在内的论点也适用于一般情况,因此似乎没有特定的缺点。从技术上讲,此方法已包含在 Ruby on Rails 框架中,因此作者分享了您的观点,支持将其作为自然表达。