proc可以与Ruby 2.0中的case语句一起使用吗?

Can procs be used with case statements in Ruby 2.0?

我记得Ruby2.0中的case语句中允许使用proc,但我不能谷歌搜索它。

我尝试查看Ruby2.0.0新闻以及如何用Ruby编写switch语句。我还访问了http://ruby-doc.org,但是它的关键字链接是Ruby1.9,而不是Ruby2.0。

在case语句中是否允许procs?


对。

1
2
3
4
5
6
7
8
9
10
11
12
2.0.0p0 :001> lamb = ->(x){ x%2==1 }
#=> #<Proc:0x007fdd6a97dd90@(irb):1 (lambda)>

2.0.0p0 :002> case 3; when lamb then p(:yay); end
:yay
#=> :yay

2.0.0p0 :003> lamb === 3
#=> true

2.0.0p0 :007> lamb === 2
#=> false

然而,这与1.9.1没有什么不同,因为Proc#===是在当时定义的。由于Ruby文档在显示这种方法时似乎有问题,为了清楚起见,文档中说proc === obj

Invokes the block with obj as the proc's parameter like #call. It is to allow a proc object to be a target of when clause in a case statement.

对于Ruby初学者来说,Ruby的case语句中的when子句接受子句中的值,并对其调用===方法,将参数传递给case语句。例如,这段代码…

1
2
3
4
case"cats"
  when /^cat/ then puts("line starts with cat!")
  when /^dog/ then puts("line starts with dog!")
end

…运行/^cat/ ==="cats"来决定是否匹配;RegExp类定义===方法来执行regex匹配。因此,您可以在when子句中使用自己的对象,只要您为它定义===即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Moddable = Struct.new(:n) do
  def ===(numeric)
    numeric % n == 0
  end
end

mod4 = Moddable.new(4)
mod3 = Moddable.new(3)

12.times do |i|
  case i
    when mod4
      puts"#{i} is a multiple of 4!"
    when mod3
      puts"#{i} is a multiple of 3!"
  end
end

#=> 0 is a multiple of 4!
#=> 3 is a multiple of 3!
#=> 4 is a multiple of 4!
#=> 6 is a multiple of 3!
#=> 8 is a multiple of 4!
#=> 9 is a multiple of 3!