Comment écrire une déclaration switch dans Ruby?
Comment puis-je écrire une déclaration d'échange dans Ruby?
21 réponses
Ruby utilise case
expression à la place.
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 compare l'objet dans la clause when
avec l'objet dans la clause case
en utilisant l'opérateur ===
. Par exemple, 1..5 === x
, et non x === 1..5
.
cela permet des clauses sophistiquées when
comme vu ci-dessus. Les gammes, les classes et toutes sortes de choses peuvent être testées pour plus que juste l'égalité.
Contrairement aux déclarations de switch
dans de nombreuses autres langues, case
de Ruby n'a pas fall-through , il n'est donc pas nécessaire de terminer chaque when
par un break
. Vous pouvez également spécifier plusieurs correspondances dans une seule clause when
comme when "foo", "bar"
.
case...when
se comporte un peu de façon inattendue lors de la manipulation des classes. Cela est dû au fait qu'il utilise l'opérateur ===
.
Que l'opérateur fonctionne comme prévu avec des littéraux, mais pas avec des classes:
1 === 1 # => true
Fixnum === Fixnum # => false
cela signifie que si vous voulez faire un case ... when
sur la classe d'un objet, cela ne fonctionnera pas:
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
imprimé "Ce n'est pas une chaîne".
heureusement, ceci est facilement résolu. L'opérateur ===
a été défini de sorte qu'il retourne true
si vous l'utilisez avec une classe et fournissez une instance de cette classe comme deuxième opérande:
Fixnum === 1 # => true
en bref, le code ci-dessus peut être corrigé en supprimant le .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
j'ai frappé ce problème aujourd'hui tout en cherchant une réponse, et ce fut la première page apparaissant, donc j'ai pensé qu'il serait utile à d'autres dans mon même situation.
C'est fait par cas en Ruby. Voir aussi cet article sur Wikipedia .
Citée:
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
autre exemple:
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
autour de la page 123 (j'utilise Kindle) de la programmation Ruby Lanugage (1ère Édition, O'Reilly), il est dit le mot-clé then
suivant les clauses when
peut être remplacé par une nouvelle ligne ou point-virgule (comme dans la syntaxe if then else
). (Ruby 1.8 permet également un colon à la place de then
... Mais cette syntaxe n'est plus permise dans Ruby 1.9.)
...quand
pour ajouter d'autres exemples à réponse de Chuck :
avec paramètre:
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
sans paramètre:
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
s'il vous Plaît, soyez conscient de la question que kikito, avertit le rapport.
de nombreux langages de programmation, en particulier ceux dérivés de C, prennent en charge le soi-disant Switch Fallthrough . Je cherchais la meilleure façon de faire la même chose à Ruby et j'ai pensé que cela pourrait être utile à d'autres:
En C-comme langues fallthrough ressemble généralement à ceci:
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;
}
dans Ruby, la même chose peut être réalisée de la manière suivante:
case expression
when 'a', 'b', 'c'
# Do something for a, b or c
when 'd', 'e'
# Do something else for d or e
end
Ce n'est pas strictement équivalent, parce qu'il n'est pas possible de laisser 'a'
exécuter un bloc de code avant de tomber dans 'b'
ou 'c'
, mais pour la plupart je le trouve assez similaire pour être utile de la même manière.
dans Ruby 2.0, vous pouvez également utiliser lambdas dans case
déclarations, comme suit:
is_even = ->(x) { x % 2 == 0 }
case number
when 0 then puts 'zero'
when is_even then puts 'even'
else puts 'odd'
end
vous pouvez également créer vos propres comparateurs facilement en utilisant une structure avec un personnalisé ===
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
(exemple tiré de " ) est-ce que procs peut être utilisé avec les déclarations de cas dans Ruby 2.0? ".)
ou, avec une classe complète:
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
(exemple tiré de " Comment Un Rubis Cas De Déclaration De Travaux Et De Ce Que Vous Pouvez Faire Avec Lui ".)
vous pouvez utiliser des expressions régulières, comme trouver un type de chaîne de caractères:
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
utilisera l'opérande d'égalité ===
pour ceci (merci @JimDeville). Des informations supplémentaires sont disponibles au " Ruby Operators ". Cela peut également être fait en utilisant l'exemple @mmdemirbas (sans paramètre), seulement cette approche est plus propre pour ces types de cas.
si vous êtes désireux de savoir comment utiliser un OR dans un boîtier Ruby switch:
Alors, dans un case
, l'énoncé ,
est l'équivalent de ||
dans un if
.
case car
when 'Maruti', 'Hyundai'
# Code here
end
beaucoup d'autres choses que vous pouvez faire avec une déclaration de cas de rubis
ça s'appelle case
et ça marche comme on pourrait s'y attendre, en plus de beaucoup plus de choses amusantes grâce à ===
qui implémente les tests.
case 5
when 5
puts 'yes'
else
puts 'else'
end
Maintenant, pour le plaisir:
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
et il s'avère que vous pouvez aussi remplacer une chaîne if/else arbitraire (c'est-à-dire, même si les tests n'impliquent pas une variable commune) par case
en laissant de côté le paramètre initial case
et en écrivant simplement des expressions où la première le match est ce que vous voulez.
case
when x.nil?
...
when (x.match /'^fn'/)
...
when (x.include? 'substring')
...
when x.gsub('o', 'z') == 'fnzrq'
...
when Time.now.tuesday?
...
end
selon votre cas, vous pourriez préférer utiliser un hachage de méthodes.
S'il y a une longue liste de quand et que chacun d'eux a une valeur concrète à comparer avec (pas un intervalle), il sera plus efficace de déclarer un hachage de méthodes et ensuite d'appeler la méthode pertinente du hachage comme cela.
# 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])
puisque switch case
renvoie toujours un seul objet, nous pouvons directement imprimer son résultat:
puts case a
when 0
"It's zero"
when 1
"It's one"
end
Multi-valeur quand et la non-valeur de cas:
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
et une expression régulière solution ici:
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
Ruby utilise le case
pour écrire des énoncés d'interrupteur.
selon le Ruby Docs :
Cas énoncés sont d'une condition facultative, qui est dans le la position d'un argument
case
, et zéro ou plusieurswhen
clauses. La première clausewhen
pour correspondre à la condition (ou pour évaluer à Boolean truth, si la condition est nulle) "gagne", et son code stanza est exécutée. La valeur de l'instruction de cas est la valeur de lawhen
ounil
s'il n'existe pas de telle clause.un énoncé de cas peut se terminer par une clause
else
. Chaquewhen
a l'instruction peut avoir plusieurs valeurs candidates, séparées par des virgules.
exemple:
case x
when 1,2,3
puts "1, 2, or 3"
when 10
puts "10"
else
puts "Some other number"
end
version courte:
case x
when 1,2,3 then puts "1, 2, or 3"
when 10 then puts "10"
else puts "Some other number"
end
et comme ce blog par Honeybadger décrit le cas Ruby;
peut être utilisé avec gammes :
case 5
when (1..10)
puts "case statements match inclusion in a range"
end
## => "case statements match inclusion in a range"
peut être utilisé avec Regex :
case "FOOBAR"
when /BAR$/
puts "they can match regular expressions!"
end
## => "they can match regular expressions!"
peut être utilisé avec Procs et Lambdas :
case 40
when -> (n) { n.to_s == "40" }
puts "lambdas!"
end
## => "lambdas"
aussi, peut être utilisé avec vos propres classes de match:
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
vous pouvez écrire des expressions de cas de deux façons différentes dans ruby.
- semblable à une série d'énoncés" si
- spécifie une cible à côté du cas et chaque clause" quand " est comparée à la cible.
1ère méthode
age = 20
case
when age >= 21
puts "display something"
when 1 == 0
puts "omg"
else
puts "default condition"
end
2ème
case params[:unknown]
when /Something/ then 'Nothing'
when /Something else/ then 'I dont know'
end
beaucoup de bonnes réponses mais j'ai pensé que je voudrais ajouter un factoid.. Si vous essayez de comparer des objets (Classes) assurez-vous d'avoir une méthode de vaisseau spatial (pas une blague) ou de comprendre comment ils sont comparés
Voici une bonne discussion sur le sujet http://www.skorks.com/2009/09/ruby-equality-and-object-comparison /
Vous pouvez le faire comme cela plus de façon naturelle,
case expression
when condtion1
function
when condition2
function
else
function
end
puts "Recommend me a language to learn?"
input = gets.chomp.downcase.to_s
case input
when 'ruby'
puts "Learn Ruby"
when 'python'
puts "Learn Python"
when 'java'
puts "Learn Java"
when 'php'
puts "Learn PHP"
else
"Go to Sleep!"
end
comme indiqué dans la plupart des réponses ci-dessus, l'opérateur === est utilisé sous la hotte sur les instructions case/when.
voici quelques informations supplémentaires sur cet opérateur.
opérateur d'égalité de cas: = = = =
plusieurs des classes intégrées de Ruby, telles que String, Range et Regexp, fournissent leurs propres implémentations de l'opérateur===, aussi connu sous le nom de case-equality, Triple equals ou threeequals. Parce qu'il est mis en œuvre différemment dans chaque classe, il va se comporter différemment selon le type d'objet, il a été appelé. Généralement, elle renvoie true si l'objet sur la droite "appartient à" ou "est un membre de" l'objet sur la gauche. Par exemple, il peut être utilisé pour tester si un objet est une instance d'une classe (ou un de ses sous-classes).
String === "zen" # Output: => true
Range === (1..2) # Output: => true
Array === [1,2,3] # Output: => true
Integer === 2 # Output: => true
Le même résultat peut être obtenu avec d'autres méthodes qui sont probablement les mieux adaptés pour le travail, comme is_a? et instance_of?.
Gamme de la mise en Œuvre de l' ===
quand l'opérateur === est appelé sur un objet range, il renvoie true si la valeur à droite se situe dans la plage à gauche.
(1..4) === 3 # Output: => true
(1..4) === 2.345 # Output: => true
(1..4) === 6 # Output: => false
("a".."d") === "c" # Output: => true
("a".."d") === "e" # Output: => false
rappelez-vous que l'opérateur === invoque la méthode === de l'objet de gauche. So (1..4) === 3 est équivalent à (1..4).= = = 3. En d'autres termes, la classe de l'opérande de gauche définira quelle implémentation de la méthode === sera appelée, si l'opérande de postes ne sont pas interchangeables.
Regexp mise en Œuvre de l' ===
renvoie true si la chaîne de caractères à droite correspond à l'expression régulière à gauche. /zen/ === "la pratique de zazen aujourd'hui" # Sortie: => true # est similaire à "la pratique de zazen aujourd'hui"=~ /zen/
La seule différence entre les deux exemples ci-dessus, c'est que, lorsqu'il existe une correspondance, === retourne true et =~ renvoie un entier, ce qui est une valeur vraie dans Ruby. Nous reviendrons à ce sujet bientôt.
$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
j'ai commencé à utiliser:
a = "secondcase"
var_name = case a
when "firstcase" then "foo"
when "secondcase" then "bar"
end
puts var_name
>> "bar"
il aide le code compact dans certains cas.
pas de support pour les expressions régulières dans votre environnement? Par exemple: Shopify Script Editor (April, 2018):
[erreur]: constante non initialisée RegExp
Une solution de contournement à la suite d'une combinaison de méthodes déjà précédemment dans ici et ici :
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
j'ai utilisé or
s dans la classe de déclaration de méthode depuis ||
a une priorité plus élevée que
.include?
. Si vous êtes un ruby-nazi , s'il vous plaît imaginez que j'ai utilisé ce (item.include? 'A') || ...
à la place. repl. .