Performing numeric operations in Ruby case statement

In a recent project, I wrote a standard case statement which runs a conditional based on the outcome of performing a numeric operation on a value.

A sample of the code is as follows:

1 n = 2
2 
3 case n
4 when (n % 2 ==0) then "even"
5 else puts "odd"
6 end

In theory, the output should be even given that n is divisible by 2. However, the above will output odd despite what the value of n is. This is due to the way when works in a case statement.

From the above example, the when statement is translated as:

1 (n % 2 == 0) === n # => false

which will always return false, hence printing odd no matter what variable n holds.

The only way to handle numeric operations in Ruby case statements is to encapsulate it inside a proc and use that in the when statement. Rewriting the above:

 1 even = ->(x){ x % 2 == 0 }
 2 
 3 n = 2
 4 
 5 res = case n
 6 when even "even"
 7 else "odd"
 8 end
 9 
10 res # => "even"

This works because underneath the hood, proc aliases the threequals === operator to the call method. It is important to realise that the === operator is a method and should not be treated as an equality operation.

This has actually caused me some confusion and led to some debugging. I hope it helps someone with a similar issue.

Stay curious and keep hacking!