Можно ли использовать procs с аргументами case в Ruby 2.0?

Я помню кое-что о том, что procs допускается в операторах case в Ruby 2.0, но я не могу его использовать.

Я попытался проверить Ruby 2.0.0 NEWS и Как написать оператор switch в Ruby. Я также посетил http://ruby-doc.org, но ссылка для ключевых слов была для Ruby 1.9, а не Ruby 2.0.

Разрешены ли procs в операторах case?

Ответ 1

Да.

2.0.0p0 :001> lamb = ->(x){ x%2==1 }
#=> #<Proc:[email protected](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-docs, похоже, проблема с этим методом, чтобы быть ясным, в документации говорится, что proc === obj:

Вызывает блок с obj как параметр proc, например #call. Это означает, что объект proc является целью when в выражении case.


Для новичка Ruby предложение when в операторах Ruby case принимает значение в предложении и вызывает на нем метод ===, передавая аргумент аргументу case. Так, например, этот код...

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

... запускает /^cat/ === "cats", чтобы решить, является ли это совпадением; класс RegExp определяет метод === для выполнения сопоставления регулярных выражений. Таким образом, вы можете использовать свой собственный объект в предложении when, пока вы определяете для него ===.

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!