Shortcut to make case/switch return a value
I'm pretty sure I saw someone do a shortcut technique like the code below (which doesn't work)
return case guess
when guess > @answer then :high
when guess < @answer then :low
else :correct
end
Does anyone know the trick I'm referring to?
A case
statement does return a value, you just have to use the right form of it to get the value you're expecting.
There are two forms of case
in Ruby. The first one looks like this:
case expr
when expr1 then ...
when expr2 then ...
else ...
end
This will compare expr
with each when
expression using ===
(that's a triple BTW) and it will execute the first then
where ===
gives a true value. For example:
case obj
when Array then do_array_things_to(obj)
when Hash then do_hash_things_to(obj)
else raise 'nonsense!'
end
is the same as:
if(Array === obj)
do_array_things_to(obj)
elsif(Hash === obj)
do_hash_things_to(obj)
else
raise 'nonsense!'
end
The other form of case
is just a bunch of boolean conditions:
case
when expr1 then ...
when expr2 then ...
else ...
end
For example:
case
when guess > @answer then :high
when guess < @answer then :low
else :correct
end
is the same as:
if(guess > @answer)
:high
elsif(guess < @answer)
:low
else
:correct
end
You're using the first form when you think you're using the second form so you end up doing strange (but syntactically valid) things like:
(guess > @answer) === guess
(guess < @answer) === guess
In either case, case
is an expression and returns whatever the matched branch returns.
You need to remove the guess
from the case
, because it's not valid ruby syntax.
For example:
def test value
case
when value > 3
:more_than_3
when value < 0
:negative
else
:other
end
end
Then
test 2 #=> :other
test 22 #=> :more_than_3
test -2 #=> :negative
The return
is implicit.
Edit: you can use then
if you like too, the same example would look like this:
def test value
case
when value > 3 then :more_than_3
when value < 0 then :negative
else :other
end
end
This works:
return case
when guess > @answer ; :high
when guess < @answer ; :low
else ; :correct
end