tags:

views:

55

answers:

3

Hi,

I have the following code with a small bug in it, the case statement returns the value "other" even though the first "when" statement evaluates true and should return "boats".

I've been been looking at this for ages, must be something small.

CATEGORIES = {:boats  => [1, 2, 3, 4, 5, 6],
              :houses => [7, 8, 9, 10],
              :other  => [11,12,13,14,15,16]
             }

category_id = 1

category = case category_id
  when CATEGORY_CLASSES[:boats].include?(category_id); "boats"
  when CATEGORY_CLASSES[:houses].include?(category_id); "houses"
  else "other"
end

Thanks!

A: 

There is no :cars label in your hash. So it's impossible to return "boats"

AShelly
would have been better as a comment on the question
glenn jackman
+4  A: 

(I'm going to ignore the fact that your hash does not actually contain any of the keys you were checking for and pretend you're checking for keys that are actually in the hash. Hopefully this is the right assumption.)

You appear to misunderstand what a case statement is. It's testing the value of the object of the case statement, not merely running a bunch of vaguely related ifs. The when-clauses are all compared with === to the object of the case statement. So if you write CATEGORY_CLASSES[:boats].include?(category_id), then it either means if true === category_id or if false === category_id (since include? returns either true or false).

What you want is more like CATEGORIES.find {|k,v| v.include? category_id}.first.to_s.

Chuck
+5  A: 

A case statement is usually just a shorthand for an if statement. Yours can be rewritten as:

if CATEGORY_CLASSES[:boats].include?(category_id) === category_id
  category = "boats"
elsif CATEGORY_CLASSES[:houses].include?(category_id) === category_id
  category = "houses"
else
  category = "other"
end

When you look at it in this form, you should see the problem clearly; while include? returns a boolean, you're comparing it against an integer value.

Daniel Vandersluis
Actually `case` uses `===`, not `==`, but in this case the difference doesn't matter.
sepp2k
@sepp2k my bad, that's what I meant to write.
Daniel Vandersluis