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:51

Many programming languages, especially those derived from C, have support for the so-called Switch Fallthrough. I was searching for the best way to do the same in Ruby and thought it might be useful to others:

In C-like languages fallthrough typically looks like this:

switch (expression) {
    case 'a':
    case 'b':
    case 'c':
        // Do something for a, b or c
        break;
    case 'd':
    case 'e':
        // Do something else for d or e
        break;
}

In Ruby, the same can be achieved in the following way:

case expression
when 'a', 'b', 'c'
  # Do something for a, b or c
when 'd', 'e'
  # Do something else for d or e
end

This is not strictly equivalent, because it's not possible to let 'a' execute a block of code before falling through to 'b' or 'c', but for the most part I find it similar enough to be useful in the same way.

查看更多
墨雨无痕
3楼-- · 2018-12-31 23:51
$age =  5
case $age
when 0 .. 2
   puts "baby"
when 3 .. 6
   puts "little child"
when 7 .. 12
   puts "child"
when 13 .. 18
   puts "youth"
else
   puts "adult"
end

reference => https://www.tutorialspoint.com/ruby/ruby_if_else.htm

查看更多
何处买醉
4楼-- · 2018-12-31 23:55

You can use regular expressions, such as finding a type of string:

case foo
when /^(true|false)$/
   puts "Given string is boolean"
when /^[0-9]+$/ 
   puts "Given string is integer"
when /^[0-9\.]+$/
   puts "Given string is float"
else
   puts "Given string is probably string"
end

Ruby's case will use the equality operand === for this (thanks @JimDeville). Additional information is available at "Ruby Operators". This also can be done using @mmdemirbas example (without parameter), only this approach is cleaner for these types of cases.

查看更多
墨雨无痕
5楼-- · 2018-12-31 23:57

Ruby uses the case for writing switch statements.

As per the Ruby Docs:

Case statements consist of an optional condition, which is in the position of an argument to case, and zero or more when clauses. The first when clause to match the condition (or to evaluate to Boolean truth, if the condition is null) “wins”, and its code stanza is executed. The value of the case statement is the value of the successful when clause, or nil if there is no such clause.

A case statement can end with an else clause. Each when a statement can have multiple candidate values, separated by commas.

Example:

case x
when 1,2,3
  puts "1, 2, or 3"
when 10
  puts "10"
else
  puts "Some other number"
end

Shorter version:

case x
when 1,2,3 then puts "1, 2, or 3"
when 10 then puts "10"
else puts "Some other number"
end

And as this blog by Honeybadger describes Ruby Case;

Can be used with Ranges:

case 5
when (1..10)
  puts "case statements match inclusion in a range"
end

## => "case statements match inclusion in a range"

Can be used with Regex:

case "FOOBAR"
when /BAR$/
  puts "they can match regular expressions!"
end

## => "they can match regular expressions!"

Can be used with Procs and Lambdas:

case 40
when -> (n) { n.to_s == "40" }
  puts "lambdas!"
end

## => "lambdas"

Also, can be used with your own match classes:

class Success
  def self.===(item)
    item.status >= 200 && item.status < 300
  end
end

class Empty
  def self.===(item)
    item.response_size == 0
  end
end

case http_response
when Empty
  puts "response was empty"
when Success
  puts "response was a success"
end
查看更多
伤终究还是伤i
6楼-- · 2018-12-31 23:59

Lots of great answers but I thought I would add one factoid.. If you are attempting to compare objects (Classes) make sure you have a space ship method (not a joke) or understand how they are being compared

Here is a good discussion on the topic http://www.skorks.com/2009/09/ruby-equality-and-object-comparison/

查看更多
高级女魔头
7楼-- · 2018-12-31 23:59

No support for regular expressions in your environment? E.g. Shopify Script Editor (April, 2018):

[Error]: uninitialized constant RegExp

A workaround following a combination of methods already previously covered in here and here:

code = '!ADD-SUPER-BONUS!'

class StrContains
  def self.===(item)
    item.include? 'SUPER' or item.include? 'MEGA' or\
    item.include? 'MINI' or item.include? 'UBER'
  end
end

case code.upcase
when '12345PROMO', 'CODE-007', StrContains
  puts "Code #{code} is a discount code!"
when '!ADD-BONUS!'
  puts 'This is a bonus code!'
else
  puts 'Sorry, we can\'t do anything with the code you added...'
end

I used ors in the class method statement since || has higher precedence than .include?. If you are a ruby-nazi, please imagine I used this (item.include? 'A') || ... instead. repl.it test.

查看更多
登录 后发表回答