Dan Rubio - 1 year ago 74
Ruby Question

# Why is my case statement failing despite the condition being true?

I'm working on a kata that tallies scores based on the role of five six sided die. Here is my code so far:

``````def score( dice )
points = []
score = {}
dice.each do |n|
if score.has_key?(n.to_s.to_sym)
score[n.to_s.to_sym] += 1
else
score[n.to_s.to_sym] = 1
end
end

score.each do |k,v|
key_int = k.to_s.to_i

case key_int
when key_int == 1 && (v == 3)
points << 1000
when key_int == 6 && (v == 3)
points << 600
when key_int == 5 && (v == 3)
points << 500
when key_int == 4 && (v == 3)
points << 400
when key_int == 3 && (v == 2)
points << 300
when key_int == 2 && (v == 3)
puts "did I get here"
points << 200
when key_int == 1 && (v < 3)
points << key_int * v
when key_int == 5 && (v < 3)
points << key_int * v
else
puts "Default"
end
end
points
end

puts score([2, 2, 2, 3, 3]) ==> 200
``````

So at a basic level for this example, what's happening is when my each loop hits the hash I get this condition of:

``````key_int == 2 && (v == 3)
``````

and insert it into the code before the case statement, I get a value of
`true`
but I never reach the condition of
`points << 200`
. For simplification I whittled down the code to this for the case logic.

``````score.each do |k,v|
key_int = k.to_s.to_i
case key_int
when key_int == 2
puts "I reached the condition"
else
puts "default"
end
end
``````

I still get the default and I never reach the
`when`
condition. This is confusing me. What am I possibly doing wrong?

If you specify an object right after `case`, it will be compared against each `when` pattern via `pattern === object`.

In this example:

``````case key_int
when key_int == 2
# ...
end
``````

it will compare `key_int` against `key_int == 2` like this:

``````(key_int == 2) === key_int
``````

Assuming that `key_int` is `2`, the above becomes:

``````true === 2
``````

which evaluates to `false`.

To use a `case` expression like an `if-elsif` expression, you have to omit the initial object:

``````case
when key_int == 2
# ...
end
``````

See Ruby's documentation on the `case` Expression for another example.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download