How to write a switch statement in Ruby

2018-12-31 23:16发布

How do I write a switch statement in Ruby?

21条回答
美炸的是我
2楼-- · 2018-12-31 23:44

I've started to use:

a = "secondcase"

var_name = case a
  when "firstcase" then "foo"
  when "secondcase" then "bar"
end

puts var_name
>> "bar"

It helps compact code in some cases.

查看更多
情到深处是孤独
3楼-- · 2018-12-31 23:46

Multi-value when and no-value case:

print "Enter your grade: "
grade = gets.chomp
case grade
when "A", "B"
  puts 'You pretty smart!'
when "C", "D"
  puts 'You pretty dumb!!'
else
  puts "You can't even use a computer!"
end

And a regular expression solution here:

print "Enter a string: "
some_string = gets.chomp
case
when some_string.match(/\d/)
  puts 'String has numbers'
when some_string.match(/[a-zA-Z]/)
  puts 'String has letters'
else
  puts 'String has no numbers or letters'
end
查看更多
深知你不懂我心
4楼-- · 2018-12-31 23:48

Ruby uses the case expression instead.

case x
when 1..5
  "It's between 1 and 5"
when 6
  "It's 6"
when "foo", "bar"
  "It's either foo or bar"
when String
  "You passed a string"
else
  "You gave me #{x} -- I have no idea what to do with that."
end

Ruby compares the object in the when clause with the object in the case clause using the === operator. For example, 1..5 === x, and not x === 1..5.

This allows for sophisticated when clauses as seen above. Ranges, classes and all sorts of things can be tested for rather than just equality.

Unlike switch statements in many other languages, Ruby’s case does not have fall-through, so there is no need to end each when with a break. You can also specify multiple matches in a single when clause like when "foo", "bar".

查看更多
大哥的爱人
5楼-- · 2018-12-31 23:48

case...when behaves a bit unexpectedly when handling classes. This is due to the fact that it uses the === operator.

That operator works as expected with literals, but not with classes:

1 === 1           # => true
Fixnum === Fixnum # => false

This means that if you want to do a case ... when over an object's class, this will not work:

obj = 'hello'
case obj.class
when String
  print('It is a string')
when Fixnum
  print('It is a number')
else
  print('It is not a string')
end

Will print "It is not a string".

Fortunately, this is easily solved. The === operator has been defined so that it returns true if you use it with a class and supply an instance of that class as the second operand:

Fixnum === 1 # => true

In short, the code above can be fixed by removing the .class:

obj = 'hello'
case obj  # was case obj.class
when String
  print('It is a string')
when Fixnum
  print('It is a number')
else
  print('It is not a string')
end

I hit this problem today while looking for an answer, and this was the first appearing page, so I figured it would be useful to others in my same situation.

查看更多
余欢
6楼-- · 2018-12-31 23:48

It is done by case in Ruby. Also see this article on Wikipedia.

Quoted:

case n
when 0
  puts 'You typed zero'
when 1, 9
  puts 'n is a perfect square'
when 2
  puts 'n is a prime number'
  puts 'n is an even number'
when 3, 5, 7
  puts 'n is a prime number'
when 4, 6, 8
  puts 'n is an even number'
else
  puts 'Only single-digit numbers are allowed'
end

Another example:

score = 70

result = case score
   when 0..40 then "Fail"
   when 41..60 then "Pass"
   when 61..70 then "Pass with Merit"
   when 71..100 then "Pass with Distinction"
   else "Invalid Score"
end

puts result

On around page 123 (I am using Kindle) of The Ruby Programming Lanugage (1st Edition, O'Reilly), it says the then keyword following the when clauses can be replaced with a newline or semicolon (just like in the if then else syntax). (Ruby 1.8 also allows a colon in place of then... But this syntax is no longer allowed in Ruby 1.9.)

查看更多
大哥的爱人
7楼-- · 2018-12-31 23:48

Since switch case always returns a single object, we can directly print its result:

puts case a
     when 0
        "It's zero"
     when 1
        "It's one"
     end
查看更多
登录 后发表回答