Black Bytes :: The Many Uses Of Ruby Case Statements

来源:转载

Whenever you need to use some if / elsif statements you should consider using a Ruby case statement instead. In this post, you will learn a few different use cases and how it all really works under the hood.

Note: In other programming languages this is known as a switch statement.

Ranges + Case

The case statement is more flexible than it might appear at first sigh. Let’s see an example where we want to print some message depending on what range a value falls in.

case capacity

when 0

"You ran out of gas."

when 1..20

"The tank is almost empty. Quickly, find a gas station!"

when 21..70

"You should be ok for now."

when 71..100

"The tank is almost full."

else

"Error: capacity has an invalid value (#{capacity})"

end

I think this code is pretty elegant compared to what the if / elsif version would look like.

Regex + Case

You can also useregular expressions as your when condition. In the following example we have a serial_code with an initial letter that tells us how risky this product is to consume.

case serial _ code

when / / AC /

"Low risk"

when / / AL /

"Medium risk"

when / / AX /

"High risk"

else

"Unknown risk"

end

When Not to Use Case

When you have a simple 1:1 mapping, you might be tempted to do something like this.

case country

when "europe"

"http://eu.example.com"

when "america"

"http://us.example.com"

end

In my opinion it would be better to do this instead:

SITES = {

"europe" = > "http://eu.example.com" ,

"america" = > "http://us.example.com"

}

SITES [ country ]

The hash solution is more efficient and easier to work with. Don’t you think?

How case works: the === method

You might be wondering how case works under the hood. If we go back to our first example, this is what is happening:

( 1..20 ) === capacity

( 21..70 ) === capacity

( 71..100 ) === capacity

As you can see, the condition is reversed because Ruby calls === on the object on the left.

The === is just a method that can be implemented by any class. In this case Range implements it and returns true if the value is inside the range.