Friday, January 8, 2010

Section 3.2. The case Statement


Conditional Love > The case Statement




3.2. The case Statement


Ruby's case statement provides a way to express conditional logic in a succinct way. It is similar to using elsifs with colons, but you use case in place of if, and when in place of elsif.


Here is an example similar to what you saw earlier using lang with the possible symbols :en, :es, :fr, and :de:

lang = :fr

dog = case lang
when :en: "dog"
when :es: "perro"
when :fr: "chien"
when :de: "Hund"
else "dog"
end
# "chien" is assigned to dog


case/when is more convenient and terse than if/elsif/else because the logic of == is assumed—you don't have to keep retyping == or the variable name:


Ruby's case is similar to the switch statement, a familiar C construct, but case is more powerful. One of the annoying things to me about switch statements in C, C++, and Java, is that you can't switch on strings in a straightforward way (though you can in C#).


If the lang variable held a string instead of symbols, your code would look like this:

lang = "de"

dog = case lang
when "en": "dog"
when "es": "perro"
when "fr": "chien"
when "de": "Hund"
else "dog"
end
# "Hund" is assigned to dog


The next example uses several ranges to test values. A range is a range of numbers.

scale = 8
case scale
when 0: puts "lowest"
when 1..3: puts "medium-low"
when 4..5: puts "medium"
when 6..7: puts "medium-high"
when 8..9: puts "high"
when 10: puts "highest"
else puts "off scale"
end
# => high


The range 1..3 means a range of numbers from 1 to 3, inclusive. Because scale equals 8, scale matches the range 8..9 and case returns the string high. However, when you use three dots as in the range 1...5, the ending value 5 is excluded. The sets of dots, .. and ..., are called range operators; two dots includes all the numbers in the range, and three dots excludes the last value in the range. Underneath the hood, case uses the === operator from Range to test whether a value is a member of or included in a range.


 

 


No comments: