When you need to take a variety of different actions based on the value of a single variable, multiple if..elsif
tests are verbose and repetitive.
A neater alternative is provided by a case
statement. This begins with the word case
followed by the variable name to test. Then comes a series of when
sections, each of which specifies a “trigger” value followed by some code.
This code executes only when the test variable equals the trigger value:
case.rb
case( i ) when 1 then puts("It's Monday" ) when 2 then puts("It's Tuesday" ) when 3 then puts("It's Wednesday" ) when 4 then puts("It's Thursday" ) when 5 then puts("It's Friday" ) when (6..7) then puts( "Yippee! It's the weekend! " ) else puts( "That's not a real day!" ) end
constants.rb
math_pi.rb
In the previous example, I’ve used the then
keyword to separate each when
test from the code to execute. In Ruby 1.8, just as with if
tests mentioned earlier, you could use a colon as an alternative, but this syntax is not supported in Ruby 1.9:
when 1 : puts("It's Monday" ) # This works in Ruby 1.8 only!
The then
can be omitted if the test and the code to be executed are on separate lines. Unlike case
statements in C-like languages, there is no need to enter a break
keyword when a match is made in order to prevent execution trickling down through the remainder of the sections. In Ruby, once a match is made, the case
statement exits:
case_break.rb
def showDay( i ) case( i ) when 5 then puts("It's Friday" ) puts("...nearly the weekend!") when 6 then puts("It's Saturday!" ) # the following never executes when 5 then puts( "It's Friday all over again!" ) end end showDay( 5 ) showDay( 6 )
It's Friday ...nearly the weekend! It's Saturday!
You can include several lines of code between each when
condition, and you can include multiple values separated by commas to trigger a single when
block, like this:
when 6, 7 then puts( "Yippee! It's the weekend! " )
The condition in a case
statement is not obliged to be a simple variable; it can be an expression like this:
case2.rb
case( i + 1 )
You can also use noninteger types such as a string. If multiple trigger values are specified in a when
section, they may be of varying types—for example, both string and integers:
when 1, 'Monday', 'Mon' then puts( "Yup, '#{i}' is Monday" )
Here is a longer example, illustrating some of the syntactical elements mentioned earlier:
case3.rb
case( i ) when 1 then puts("It's Monday" ) when 2 then puts("It's Tuesday" ) when 3 then puts("It's Wednesday" ) when 4 then puts("It's Thursday" ) when 5 then puts("It's Friday" ) puts("...nearly the weekend!") when 6, 7 puts("It's Saturday!" ) if i == 6 puts("It's Sunday!" ) if i == 7 puts( "Yippee! It's the weekend! " ) # the following never executes when 5 then puts( "It's Friday all over again!" ) else puts( "That's not a real day!" ) end
As mentioned earlier, the when
tests on an object used in a case
statement are performed using the ===
method. So, for example, just as the ===
method returns true when an integer forms part of a range, a when
test returns true when an integer variable in a case
statement forms part of a range expression:
when (6..7) then puts( "Yippee! It's the weekend! " )
If in doubt on the effect of the ===
method for a specific object, refer to the Ruby documentation on that object’s class. Ruby’s standard classes are documented in the core API here: http://www.ruby-doc.org/.
There is an alternative form of the case
statement that is like a shorthand form of a series of if..then..else
statements. Each when
section can perform some arbitrary test and execute one or more lines of code. No case
variable is required. Each when
section returns a value that, just like a method, is the result of the last piece of code that’s evaluated. This value can be assigned to a variable preceding the case
statement:
case4.rb
salary = 2000000 season = 'summer' happy = case when salary > 10000 && season == 'summer' then puts( "Yes, I really am happy!" ) 'Very happy' when salary > 500000 && season == 'spring' then 'Pretty happy' else puts( 'miserable' ) end puts( happy ) #=> 'Very happy'
18.117.99.71