Вопрос: Как написать оператор switch в Ruby?


Как написать инструкцию switch в Ruby?


1816


источник


Ответы:


Ruby использует caseвыражение вместо.

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 сравнивает объект в whenс объектом в caseс использованием ===оператор. Например, 1..5 === x, и не x === 1..5,

Это позволяет whenкак показано выше. Диапазоны, классы и всевозможные вещи можно тестировать, а не просто равенство.

В отличие от switchзаявления на многих других языках, Ruby's caseне имеет Проваливаться , поэтому нет необходимости заканчивать каждый whenс break, Вы также можете указать несколько совпадений в одном whenпредложение вроде when "foo", "bar",


2282



case...whenведет себя немного неожиданно при работе с классами. Это связано с тем, что он использует ===оператор.

Этот оператор работает так, как ожидалось, с литералами, но не с классами:

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

Это означает, что если вы хотите сделать case ... whenнад классом объекта это не сработает:

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

Будет напечатать «Это не строка».

К счастью, это легко решить. ===оператор был определен так, чтобы он возвращался trueесли вы используете его с классом и поставьте экземпляр этого класса в качестве второго операнда:

Fixnum === 1 # => true

Короче говоря, приведенный выше код можно устранить, удалив .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

Сегодня я столкнулся с этой проблемой, ища ответ, и это была первая появившаяся страница, поэтому я подумал, что это будет полезно для других в моей же ситуации.


394



Это делается путем дело в Руби. Также см Эта статья о Википедии ,

Цитируется:

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

Другой пример:

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

На странице 123 (я использую Kindle) Язык программирования Ruby (1-е издание, O'Reilly), говорится, что thenключевое слово, следующее за whenпредложения могут быть заменены символом новой строки или точкой с запятой (точно так же, как в if then elseсинтаксис). (Ruby 1.8 также позволяет использовать двоеточие вместо then... Но этот синтаксис больше не разрешен в Ruby 1.9.)


187



случай ... когда

Чтобы добавить дополнительные примеры для Ответ Чака :

С параметром:

case a
when 1
  puts "Single value"
when 2, 3
  puts "One of comma-separated values"
when 4..6
  puts "One of 4, 5, 6"
when 7...9
  puts "One of 7, 8, but not 9"
else
  puts "Any other thing"
end

Без параметра:

case
when b < 3
  puts "Little than 3"
when b == 3
  puts "Equal to 3"
when (1..10) === b
  puts "Something in closed range of [1..10]"
end

Пожалуйста, имейте в виду проблема что предупреждает кикито.


88



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.


64



In Ruby 2.0, you can also use lambdas in case statements, as follows:

is_even = ->(x) { x % 2 == 0 }

case number
when 0 then puts 'zero'
when is_even then puts 'even'
else puts 'odd'
end

You can also create your own comparators easily using a Struct with a custom ===

Moddable = Struct.new(:n) do
  def ===(numeric)
    numeric % n == 0
  end
end

mod4 = Moddable.new(4)
mod3 = Moddable.new(3)

case number
when mod4 then puts 'multiple of 4'
when mod3 then puts 'multiple of 3'
end

(Example taken from "Can procs be used with case statements in Ruby 2.0?".)

Or, with a complete class:

class Vehicle
  def ===(another_vehicle)
    self.number_of_wheels == another_vehicle.number_of_wheels
  end
end

four_wheeler = Vehicle.new 4
two_wheeler = Vehicle.new 2

case vehicle
when two_wheeler
  puts 'two wheeler'
when four_wheeler
  puts 'four wheeler'
end

(Example taken from "How A Ruby Case Statement Works And What You Can Do With It".)


63



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.


47



If you are eager to know how to use an OR condition in a Ruby switch case:

So, in a case statement, a , is the equivalent of || in an if statement.

case car
   when 'Maruti', 'Hyundai'
      # Code here
end

Many other things you can do with a Ruby case statement


29