为什么Array不覆盖Ruby中的三重等号方法?

And*_*imm 6 ruby equality language-design switch-statement

我刚刚注意到Array不会覆盖三重等号方法===,有时也称为大小写等式方法.

x = 2

case x
  when [1, 2, 3] then "match"
  else "no match"
end # => "no match"
Run Code Online (Sandbox Code Playgroud)

而范围运算符确实:

x = 2

case x
  when 1..3 then "match"
  else "no match"
end # => "match"
Run Code Online (Sandbox Code Playgroud)

但是,您可以为数组执行解决方法:

x = 2

case x
  when *[1, 2, 3] then "match"
  else "no match"
end # => "match"
Run Code Online (Sandbox Code Playgroud)

知道为什么会这样吗?

是因为它更有可能x成为一个实际的数组而不是一个范围,并且数组重写===意味着普通的相等不匹配?

# This is ok, because x being 1..3 is a very unlikely event
# But if this behavior occurred with arrays, chaos would ensue?
x = 1..3

case x
  when 1..3 then "match"
  else "no match"
end # => "no match"
Run Code Online (Sandbox Code Playgroud)

Ale*_*ski 4

因为它在规范中

it "treats a literal array as its own when argument, rather than a list of arguments"
Run Code Online (Sandbox Code Playgroud)

该规范由Charles Nutter ( @headius ) 于 2009 年 2 月 3 日添加。既然这个答案可能不是你想要的,你为什么不问他呢?

在黑暗中进行一次疯狂且完全不知情的尝试,在我看来,您可能通过在问题中使用“splat”来找到答案。既然该功能是按设计可用的,为什么重复这样做会消除测试数组相等性的能力呢?正如乔丹在上面指出的,在某些情况下这是有用的。


未来的读者应该注意,除非所讨论的数组已经实例化,否则根本不需要使用数组来匹配多个表达式:

x = 2

case x
  when 1, 2, 3 then "match"
  else "no match"
end # => "match"
Run Code Online (Sandbox Code Playgroud)