Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can procs be used with case statements in Ruby 2.0?

I remember something about procs being allowed in case statements in Ruby 2.0, but I can't google it.

I tried checking Ruby 2.0.0 NEWS and How to write a switch statement in Ruby. I also visited http://ruby-doc.org , but the link it had for keywords was for Ruby 1.9, not Ruby 2.0.

Are procs allowed in case statements?

like image 815
Andrew Grimm Avatar asked May 21 '13 04:05

Andrew Grimm


1 Answers

Yes.

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 

However, this is no different than 1.9.1 since Proc#=== was defined back then. Since ruby-docs seems to have a problem showing this method, to be clear the documentation says that 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.


For the Ruby beginner, then when clause in Ruby's case statements takes the value in the clause and calls the === method on it, passing in the argument to the case statement. So, for example, this code…

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

…runs /^cat/ === "cats" to decide if it's a match; the RegExp class defines the === method to perform regex matching. Thus, you can use your own object in a when clause as long as you define === for it.

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!
like image 114
Phrogz Avatar answered Oct 22 '22 12:10

Phrogz