Using the Case (Switch) Ruby Statement

woman working at laptop

GrapchicStock / Getty Images

In most computer languages, the case or conditional (also known as switch) statement compares the value of a variable with that of several constants or literals and executes the first path with a matching case. In Ruby, it's a bit more flexible (and powerful).

Instead of a simple equality test being performed, the case equality operator is used, opening the door to many new uses.

There are some differences from other languages though. In C, a switch statement is a kind of replacement for a series of if and goto statements. The cases are technically labels, and the switch statement will go to the matching label. This exhibits a behavior called "fallthrough," as the execution doesn't stop when it reaches another label.

This is usually avoided using a break statement, but fallthrough is sometimes intentional. The case statement in Ruby, on the other hand, can be seen as a shorthand for a series of if statements. There is no fallthrough, only the first matching case will be executed.

The Basic Form of a Case Statement

The basic form of a case statement is as follows.

As you can see, this is structured something like an if/else if/else conditional statement. The name (which we'll call the value), in this case inputted from the keyboard, is compared to each of the cases from the when clauses (i.e. cases), and the first when block with a matching case will be executed. If none of them match, the else block will be executed.

What's interesting here is how the value is compared to each of the cases. As mentioned above, in C++, and other C-like languages, a simple value comparison is used. In Ruby, the case equality operator is used.

Remember that the type of the left-hand side of a case equality operator is important, and the cases are always the left-hand side. So, for each when clause, Ruby will evaluate case === value until it finds a match.

If we were to input Bob, Ruby would first evaluate "Alice" === "Bob", which would be false since String#=== is defined as the comparison of the strings. Next, /[qrz].+/i === "Bob" would be executed, which is false since Bob doesn't begin with Q, R or Z.

Since none of the cases matched, Ruby will then execute the else clause.

How the Type Comes Into Play

A common use of the case statement is to determine the type of value and do something different depending on its type. Though this breaks Ruby's customary duck typing, it's sometimes necessary to get things done.

This works by using the Class#=== (technically, the Module#===) operator, which tests if the right-hand side is_a? left-hand side.

The syntax is simple and elegant:

Another Possible Form

If the value is omitted, the case statement works a bit differently: it works almost exactly like an if/else if/else statement. The advantages of using the case statement over an ​if statement, in this case, are merely cosmetic.

A More Compact Syntax

There are times when there are a large number of small when clauses. Such a case statement easily grows too large to fit on the screen. When this is the case (no pun intended), you can use the then keyword to put the body of the when clause on the same line.

While this makes for some very dense code, as long as each when clause is very similar, it actually becomes more readable.

When you should use single-line and multi-line when clauses are up to you, it's a matter of style. However, mixing the two is not recommended - a case statement should follow a pattern to be as readable as possible.

Case Assignment

Like if statements, case statements evaluate to the last statement in the when clause. In other words, they can be used in assignments to provide a kind of table. However, don't forget that case statements are much more powerful than simple array or hash lookups. Such a table doesn't necessarily need to use literals in the when clauses.

If there is no matching when clause and no else clause, then the case statement will evaluate to nil.