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
2
3
4
5
6
n = 2

case n
when (n % 2 ==0) then "even"
else puts "odd"
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
2
3
4
5
6
7
8
9
10
even = ->(x){ x % 2 == 0 }

n = 2

res = case n
when even "even"
else "odd"
end

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!