If you’re like me, when you started coding in Ruby last year you found the “case” statement intriguing. After years of writing in C++ and C# it was hard for you to remember Ruby’s case syntax because it can do so much more than switch statements in those languages.
So you wrote these notes to yourself as you discovered its capabilities. Except you’re not that much like me so you didn’t. But I did. I hope you find them useful.
switch/case syntaxes (remember: Ruby uses "case" and "when" where others use "switch" and "case"): # Basically if/elsif/else (notice there's nothing # after the word "case"): [variable = ] case when bool_condition statements when bool_condition statements else # the else clause is optional statements end # If you assigned 'variable =' before the case, # the variable now has the value of the # last-executed statement--or nil if there was # no match. variable=if/elsif/else does this too. # It's common for the "else" to be a 1-line # statement even when the cases are multi-line: [variable = ] case when bool_condition statements when bool_condition statements else statement end # Case on an expression: [variable = ] case expression when nil statements execute if the expr was nil when Type1 [ , Type2 ] # e.g. Symbol, String statements execute if the expr resulted in Type1 or Type2 etc. when value1 [ , value2 ] statements execute if the expr equals value1 or value2 etc. when /regexp1/ [ , /regexp2/ ] statements execute if the expr matches regexp1 or regexp 2 etc. when min1..max1 [ , min2..max2 ] statements execute if the expr is in the range from min1 to max1 or min2 to max2 etc. (use 3 dots min...max to go up to max-1) else statements end # When using case on an expression you can mix & # match different types of expressions. E.g., [variable =] case expression when nil, /regexp/, Type statements execute when the expression is nil or matches the regexp or results in Type when min..max, /regexp2/ statements execute when the expression is in the range from min to max or matches regexp2 end # You can combine matches into an array and # precede it with an asterisk. This is useful when # the matches are defined at runtime, not when # writing the code. The array can contain a # combination of match expressions # (strings, nil, regexp, ranges, etc.) [variable =] case expression when *array_1 statements execute when the expression matches one of the elements of array_1 when *array_2 statements execute when the expression matches one of the elements of array_2 end # Compact syntax with 'then': [variable =] case expression when something then statement when something then statement else statement end # Compact syntax with semicolons: [variable =] case expression when something; statement when something; statement else statement # no semicolon required end # 1-line syntax: [variable = ] case expr when {Type|value} statements end # Formatting: it's common to indent the "when" # clauses and it's also common not to. case when when else end # More idiomatic: case when when else end
Super! I just find this info yesterday. Very useful, thank you!
can you use a case in a view? if so how?
Great question, Rashantha. I assume you mean in a Rails View. The trick is to use %=, not %. Here’s an example:
<%=
case @results
when nil then "No results"
else @results.join ", "
end
%>
this is awesome!
Great! I use this post quite often as reference because I always keep forgetting how to write that ๐
wow! nice. thanks.
hi how to use case statement when the input is from the user (i.e.)using gets.i tried but it executes the default statement.
im going to create a adressbook in Ruby using XML.
My options are
1.List – List the XML file.
2.Add – Add an element into the XML file
3.Delete – Delete an element from the XML file
i want to put these three options in case statements and select one based on the user input.
value = gets (receive input from the user)
case value
when 1: list (invoke list)
when 2: add (invoke add)
when 3: delete (invoke delete)
else puts “exit”
When i give input as 1,2,or 3 only else statement is executed.
Is the syntax is right?what corrections i have to do ?
Hi Raji,
I believe the problem is your case statement is comparing a string with an integer. Type “value=gets” into IRB and then type the number 1. You’ll see that IRB tells you the result is the string “1n”.
To fix this, convert the value to an integer before comparing it to 1, 2, or 3:
case value.to_i
Hope that helps!
it worked. thank u sir
Hey, cool tips. Perhaps I’ll buy a glass of beer to that person from that chat who told me to visit your site ๐
Thanks for the help with the array example. It helped simplify my code.
Thanks, this is awesome ๐
Did I mention that I love Rails?
ahh, thank goodness for this post. The pickaxe was entirely opaque on this subject and I now know how to do if-else’s neatly AND switches all with one structure.
Many thanks.
“Except youโre not that much like me so you didnโt. But I did.”
Ha! thanks…
every since my first C class in college i have always munged the switch/case. Now that I now almost a dozen different languages. Its hopeless in remembering the syntax. Awesome post and example! Thanks.
I have a problem with the case in Ruby while trying to parse something that goes over communication line. The relevant code part is:
status=””
status=cmd.ParseANSIString()
case status
when “READY”
Monitor().SetStateName(“Ready”)
when “RUN”
Monitor().SetStateName(“Collecting”)
when “PAUSE”
Monitor().SetStateName(“Wasting”)
else
Monitor().SetStateName(status)
end
Instrument is in the READY state, however, I always fall into the else clause (outputting READY to the SetStateName). The frame is of exact length, no control characters before or after…
I am quite clueless… can you help, please?
Daniel, I would check to see if status is an *exact* match or not. E.g., look for whitespace at the beginning or end of the string (.strip) and make sure it is uppercase (.upcase).
Thanks, Brian, .strip did the trick. I was quite sure the contents of the string are exact (I have tried to cut the length of the frame in another function by one to see what will be the output, and it was “READ”), but it clearly is not the case and there is some control character added somewhere.
Once more, thank you.