为什么在ruby 1.9中可以使用===调用proc?

时间:2012-03-12 21:01:25

标签: ruby ruby-1.9 proc-object

This article提到了4种在ruby 1.9中调用proc的方法,而===就是其中之一。我不明白为什么会这样做。它是否与===的正常含义有任何关系(询问这两个对象是否是同一个对象)?

irb(main):010:0> f =-> n {[:hello, n]}
=> #
irb(main):011:0> f.call(:hello)
=> [:hello, :hello]
irb(main):012:0> f === :hello
=> [:hello, :hello]
irb(main):013:0> Object.new === Object.new
=> false
irb(main):014:0> f === f
=> [:hello, #]

4 个答案:

答案 0 :(得分:5)

请注意,与JavaScript不同,Ruby中的===与平等无关。它专门用于for case expressions

case cats.length
  when 42                         # Uses 42      === cats.length
    puts :uh
  when /cool/i                    # Uses /cool/i === cats.length
    puts :oh
  when ->(n){ n.odd? || n/3==6 }  # Passes cats.length to the proc
    puts :my
end

答案 1 :(得分:4)

This is what the docs have to say

  

允许proc对象成为when子句的目标   案例陈述。

这是一个可能是人为的例子:

even = proc { |x| x % 2 == 0 }
n = 3
case n
when even
  puts "even!"
else
  puts "odd!"
end

这是有效的,因为case/when基本上是这样执行的:

if even === n
  puts "even!"
else
  puts "odd!"
end

case/when通过在===子句的参数上调用when来检查要执行的分支,选择返回真值的第一个。

尽管它与等式运算符(==)相似,但它并不是更强或更弱的形式。我试着将===运算符视为“属于”运算符。 Class定义它,以便您可以检查对象是否属于类(即类的实例或类的子类),Range将其定义为检查参数是否属于范围(即包含在范围内),依此类推。这并没有真正使Proc案例变得更有意义,而是将其视为使自己的属于运算符的工具,就像我上面的例子;我定义了一个对象,可以确定是否属于偶数组。

答案 2 :(得分:2)

当您需要在比较时计算某些内容时,此功能在案例构建中非常有用。

is_odd  =-> n { n%2 != 0 }
is_even =-> n { n%2 == 0 }

case 5
when is_even
  puts "the number is even"
when is_odd
  puts "the number is odd"
end

=> the number is odd

答案 3 :(得分:0)

  

它是否与===的正常含义有任何关系(询问这两个对象是否是同一个对象)?

实际上,这是对Ruby中===的常见误解。它实际上并不严格用于Object#object_id比较(尽管这是它在许多常见调用中的行为)。在Ruby中,===只是subsumption

以下是来自===的{​​{1}}的描述:“Case Equality - 对于类Object,实际上是相同的 调用#==,但通常被后代覆盖 在case语句中提供有意义的语义。“

可悲的是,即使它由三个Object组成,它也没有任何与平等有关的东西:-D