March 3, 2015 by Daniel P. Clark

Ruby: The Case for Case

It’s nice to have case and when available in Ruby.  But I don’t see it used too often.  I myself don’t use it much because I’m more accustomed to just using if and else.  So let’s get into case switching.

This is your standard use of  case switching.  We check whatever variable is handed to case against each when condition.  If they match then that section of code is executed and the rest won’t be evaluated.

Alternatively you can just not hand a value to case and use when like you would with if and else.

Those are the simplest usages for case.  But wait!  It gets better.  You can evaluate the Object handed to case with a Proc in your when clause.

Proc it!

So what happens if we do a method call as the case parameter?  Lets use Time.now .  I’ll use Procs with print statements to show whether we’re getting changing information.

So from this we see that the method handed to case is executed and evaluated to a hidden internal variable from which to compare.  So it acts just like a variable for something handed to case.  Why do I say hidden?  Because there is no way to evaluate the case item inside the when block; if it’s not defined outside of case.  See here:

Here we see our inner proc with y isn’t being given any arguments which is raising an error for us.  So the when clause will get handed the object to evaluate, but the code within the when block doesn’t get to see it.  Of course this isn’t an issue if you simply assign a variable before the case statement; then it’s available throughout.

Regex

You may use regex to evaluate your case variable.

Perhaps evaluating whether a string is upper case or lower case would be the most contextually appropriate use for case ;-).  Just kidding of course.  There are methods for that.

Caution, Weirdness, Don’t Do This

Now it is possible to change the object during the when evaluation.  This can lead to none of the cases ever evaluating as true.

For this same reason it’s probably not a great idea to use a Proc as a case switch with something that changes like Time.now .

So you can see that the Proc calls a fresh result from Time.now in each when case and the time has changed between each.  So in this case you may never hit the when clause even though one of the when clauses may be true at one point during the evaluation.  Is this likely?  Probably not.  But it is possible.

You can case case statements.  A case statement returns a result just like anything else in Ruby and you can check another case against it.  Is this useful?  I don’t know.  There may be an excellent use case for it somewhere in the future.  But the more I think about it the more I think it’s not advisable.

Additional Notes

I’ve touched on self recursive (tail recursive) methods once or twice.  Aja Hammerly uses case statements for some of her conference talk demonstrations.  It was from her conference talk up on Youtube from which I learned that you can call case without passing it something to evaluate.

In my mind it’s mostly preference that leads to using if and else over case.  But at times it may be more elegant to use case.  What do you think?  What’s the best use case for case?  Also do you know of any other behaviors or oddities with case?  I’d really like to hear about it!

Hope this was both enlightening and enjoyable for you!  Please feel free to comment, share, subscribe to my RSS Feed, and follow me on twitter @6ftdan!

God Bless!
-Daniel P. Clark

Image by Tom Godber via the Creative Commons Attribution-ShareAlike 2.0 Generic License.

#case#else#if#lambda#proc#ruby#switch#switching#when