6

本文提到了 ruby​​ 1.9 中调用 procs 的 4 种方法,=== 就是其中之一。我完全不明白为什么会这样。和 === 的正常含义有什么关系(询问两个对象是不是同一个对象)?

irb(main):010:0> f =-> n {[:hello, n]}
=> #
irb(main):011:0> f.call(:hello)
=> [:你好,:你好]
irb(主):012:0> f ===:你好
=> [:你好,:你好]
irb(main):013:0> Object.new === Object.new
=> 假的
irb(主):014:0> f === f
=> [:你好,#]
4

4 回答 4

5

请注意===,与 JavaScript 不同,在 Ruby 中不是关于平等的。它专门用于case 表达式

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
于 2012-03-12T21:14:39.867 回答
4

这是文档必须说的

它是允许 proc 对象成为whencase 语句中子句的目标。

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

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案例更有意义,但可以将其视为使您自己属于运营商的工具,就像我上面的示例一样;我定义了一个对象,它可以确定某物是否属于偶数集。

于 2012-03-12T21:10:47.173 回答
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
于 2012-03-12T21:17:02.880 回答
0

和 === 的正常含义有什么关系(询问两个对象是不是同一个对象)?

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

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

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

于 2012-03-13T04:25:51.710 回答