An Adventure With Ruby Case
Today I was trying to accomplish a simple task in Ruby with my colleague, which is to "run different statements based on which group the element belongs to".
This seems so trivial that we immediately wrote down the following codes without a second thought.
But later when we were writing RSpec for our codes, we realized that this snippet of codes always puts out value retreat
.
We were so confused as we when manually try out group_a.include? an_element_value
, it does give us true
.
And we were like
So we went online trying to find some examples in order to double confirm we were writing some correct Ruby codes.
So we read the following sample codes from this blog post.
Mmmmmm. This seems correct. And our codes also seem correct.
Errr. BUT.
There seems to be something WRONG here with our expectations of our Ruby codes.
Then I suddenly realized that while I am expecting the case
to execute the when
clause where it first return true
, it is actually COMPARING THE VALUE AGAINST THE VALUE WHEN RETURNS.
It’s not conditions
based here, it’s value based! So what happened here for the sample code is actually
So of course our codes will not work! As we were comparing symbol with true
and false
boolean values, so of course it always run the else
clause lah!
And I almost felt that Ruby is doing this to me.
So I went on reading the actual documentation for case
, where I quoted below from the documentation.
Case statements consist of an optional condition, which is in the position of an argument to case, and zero or more when clauses. The first when clause to match the condition (or to evaluate to Boolean truth, if the condition is null) “wins”, and its code stanza is executed. The value of the case statement is the value of the successful when clause, or nil if there is no such clause.
A case statement can end with an else clause. Each when statement can have multiple candidate values, separated by commas.
I read this twice and finally understand what’s going on here.
SO THE CONDITION IS OPTIONAL. And if I omitted it (condition is null), it will follow my initial expectation, where the first when
clause evaluated to Boolean truth "wins".
So I should write the following codes for my case
And this works!
Oh Yeah.
What a day.
Happy coding.
Till next time.