when - ruby условные операторы
Как написать оператор switch в Ruby (14)
Как написать инструкцию switch в Ruby?
случай ... когда
Чтобы добавить еще несколько примеров к ответу Чака :
С параметром:
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
Пожалуйста, помните о проблеме , которую предупреждает кикито.
Ruby использует case
для написания операторов switch.
Согласно Ruby Docs :
Операторы case состоят из необязательного условия, которое находится в позиции аргумента к
case
, и ноль или болееwhen
клаузе. Параметр firstwhen
, чтобы соответствовать условию (или для оценки логической истины, если условие равно null) «выигрывает», и выполняется его строфа кода. Значение аргумента case - это значение успешного предложенияwhen
, илиnil
если такого предложения нет.Оператор case может закончиться предложением
else
. Каждый,when
оператор может иметь несколько значений кандидата, разделенных запятыми.
Пример:
case x
when 1,2,3
puts "1, 2, or 3"
when 10
puts "10"
else
puts "Some other number"
end
Более короткая версия:
case x
when 1,2,3 then puts "1, 2, or 3"
when 10 then puts "10"
else puts "Some other number"
end
И поскольку этот блог Honeybadger описывает случай с Ruby;
Может использоваться с Ranges :
case 5
when (1..10)
puts "case statements match inclusion in a range"
end
## => "case statements match inclusion in a range"
Может использоваться с Regex :
case "FOOBAR"
when /BAR$/
puts "they can match regular expressions!"
end
## => "they can match regular expressions!"
Может использоваться с Procs и Lambdas :
case 40
when -> (n) { n.to_s == "40" }
puts "lambdas!"
end
## => "lambdas"
Кроме того, их можно использовать со своими собственными классами совпадений:
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
В зависимости от вашего случая вы можете предпочесть использовать хеш методов.
Если есть длинный список «когда», и каждый из них имеет конкретное значение для сравнения с (а не интервал), будет более эффективным объявлять хэш методов, а затем вызывать соответствующий метод из хэша, подобного этому.
# Define the hash
menu = {a: :menu1, b: :menu2, c: :menu2, d: :menu3}
# Define the methods
def menu1
puts 'menu 1'
end
def menu2
puts 'menu 2'
end
def menu3
puts 'menu3'
end
# Let's say we case by selected_menu = :a
selected_menu = :a
# Then just call the relevant method from the hash
send(menu[selected_menu])
Вы можете использовать регулярные выражения, такие как поиск типа строки:
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
case
Ruby будет использовать операнд равенства ===
для этого (спасибо @JimDeville). Дополнительную информацию можно получить у « Ruby Operators ». Это также можно сделать с помощью примера @mmdemirbas (без параметра), только этот подход более чист для этих типов случаев.
Вы можете сделать это более естественным образом,
case expression
when condtion1
function
when condition2
function
else
function
end
Если вы хотите знать, как использовать условие ИЛИ в случае с коммутатором Ruby:
Итак, в case
a ,
является эквивалентом ||
в выражении if
.
case car
when 'Maruti', 'Hyundai'
# Code here
end
Многие другие вещи, которые вы можете сделать с утверждением case Ruby
Многие языки программирования, особенно те, которые производятся от C, поддерживают так называемый « Паттинг» . Я искал лучший способ сделать то же самое в Ruby и подумал, что это может быть полезно другим:
В C-подобных языках провал обычно выглядит следующим образом:
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;
}
В Ruby это может быть достигнуто следующим образом:
case expression
when 'a', 'b', 'c'
# Do something for a, b or c
when 'd', 'e'
# Do something else for d or e
end
Это не является строго эквивалентным, потому что невозможно выполнить 'a'
выполнить блок кода, прежде чем перейти к 'b'
или 'c'
, но по большей части я считаю его достаточно похожим, чтобы быть полезным таким же образом.
Многозначный случай и без значения:
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
И решение регулярного выражения здесь:
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
Нет поддержки регулярных выражений в вашей среде? Например, редактор скриптов Shopify (апрель 2018 года):
[Ошибка]: неинициализированная константа RegExp
Обходной путь после комбинации методов, которые ранее были рассмотрены here и 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
Я использовал or
s в инструкции метода класса, так как ||
имеет более высокий приоритет, чем .include?
, Если вы (item.include? 'A') || ...
, представьте, что я использовал это (item.include? 'A') || ...
(item.include? 'A') || ...
вместо этого. repl.it test.
Так как switch case
всегда возвращает один объект, мы можем напрямую распечатать его результат:
puts case a
when 0
"It's zero"
when 1
"It's one"
end
Это называется case
и он работает так, как вы ожидали, плюс много интересного, любезно предоставленного ===
который реализует тесты.
case 5
when 5
puts 'yes'
else
puts 'else'
end
Теперь для некоторой забавы:
case 5 # every selector below would fire (if first)
when 3..7 # OK, this is nice
when 3,4,5,6 # also nice
when Fixnum # or
when Integer # or
when Numeric # or
when Comparable # (?!) or
when Object # (duhh) or
when Kernel # (?!) or
when BasicObject # (enough already)
...
end
И оказывается, вы также можете заменить произвольную цепочку if / else (то есть, даже если тесты не включают в себя общую переменную) с case
, оставив исходный параметр case
и просто записывая выражения, где первое совпадение - это то, что вы хочу.
case
when x.nil?
...
when (x.match /'^fn'/)
...
when (x.include? 'substring')
...
when x.gsub('o', 'z') == 'fnzrq'
...
when Time.now.tuesday?
...
end
Я начал использовать:
a = "secondcase"
var_name = case a
when "firstcase" then "foo"
when "secondcase" then "bar"
end
puts var_name
>> "bar"
В некоторых случаях это помогает компактному коду.
Вместо этого 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
.
Это позволяет использовать сложные предложения, как показано выше. Диапазоны, классы и всевозможные вещи можно тестировать, а не просто равенство.
В отличие от операторов switch
на многих других языках, case
Ruby не имеет fall-through , поэтому нет необходимости заканчивать каждый раз, when
происходит break
. Вы также можете указать несколько совпадений в одном, when
предложение, например, when "foo", "bar"
.
$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