Comment rédiger un switch
en Ruby ?
Vous pouvez aussi faire du regex sur l'argument passé : quand /thisisregex/ ligne suivante met "C'est la correspondance trouvée nr. 1 #{$1}" end
Ruby utilise le 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 le when
avec l'objet dans la clause case
en utilisant la clause ===
opérateur. Par exemple, 1..5 === x
et non x === 1..5
.
Cela permet de sophistiquer when
comme indiqué ci-dessus. Il est possible de tester des plages, des classes et toutes sortes de choses, et pas seulement l'égalité.
Contrairement à switch
dans beaucoup d'autres langages, les instructions de Ruby case
n'a pas passage à travers Il n'est donc pas nécessaire de terminer chaque when
avec un break
. Vous pouvez également spécifier plusieurs correspondances dans un seul when
comme when "foo", "bar"
.
Vous pouvez aussi faire du regex sur l'argument passé : quand /thisisregex/ ligne suivante met "C'est la correspondance trouvée nr. 1 #{$1}" end
Il convient également de noter que vous pouvez raccourcir votre code en plaçant la balise when
y return
sur la même ligne : when "foo" then "bar"
Important : Contrairement à switch
dans beaucoup d'autres langages, les instructions de Ruby case
n'a PAS passage à travers Il n'est donc pas nécessaire de terminer chaque when
avec un break
.
case...when
se comporte de manière un peu inattendue lors de la manipulation des classes. Cela est dû au fait qu'il utilise l'attribut ===
opérateur.
Cet opérateur fonctionne comme prévu avec les littéraux, mais pas avec les 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 or number')
end
Imprime "Ce n'est pas une chaîne ou un nombre".
Heureusement, ce problème est facilement résolu. Le site ===
a été défini de manière à ce qu'il renvoie 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 l'option .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 or number')
end
J'ai rencontré ce problème aujourd'hui en cherchant une réponse, et c'est la première page qui est apparue, alors j'ai pensé que cela pourrait être utile à d'autres personnes dans la même situation que moi.
Avoir le .class
est intéressant à noter, merci. Bien sûr, il s'agit d'un comportement tout à fait approprié (bien que je puisse voir comment il pourrait être une erreur commune de penser que ce serait imprimé ). It is a string
)... vous testez le classe d'un objet arbitraire, et non l'objet lui-même. Donc, par exemple : case 'hello'.class when String then "String!" when Class then "Class!" else "Something else" end
résultats dans : "Class!"
Cela fonctionne de la même manière pour 1.class
, {}.class
etc. Abandon de .class
on obtient "String!"
o "Something else"
pour ces différentes valeurs.
Merci pour cela ! c'est plus élégant que ma solution qui consistait à utiliser "case obj.class.to_s".
Cela se fait en utilisant case
en Ruby. Voir aussi " Déclaration de commutation "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
Un 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
Aux alentours de la page 123 de Le langage de programmation Ruby (1ère édition, O'Reilly) sur mon Kindle, il est dit que le then
après le mot-clé when
peuvent être remplacées par un saut de ligne ou un point-virgule (comme dans la clause if then else
). (Ruby 1.8 autorise également l'utilisation de deux points à la place de then
mais cette syntaxe n'est plus autorisée dans Ruby 1.9).
C'est la réponse que j'ai utilisée, car je définis une variable basée sur les résultats d'un switch de cas. Plutôt que de dire type = #{score}
chaque ligne, je peux simplement copier ce que vous avez fait. C'est beaucoup plus élégant. J'aime aussi beaucoup mieux les phrases d'une seule ligne (si possible).
Je sais que ça n'a rien à voir avec l'essence de la réponse, mais 4 est aussi un carré parfait.
Pour ajouter d'autres exemples à La 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, faites attention à " Comment écrire une instruction switch en Ruby " dont Kikito nous met en garde.
En Ruby 2.0, vous pouvez également utiliser les lambdas dans les éléments suivants case
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 facilement vos propres comparateurs en utilisant une structure avec une fonction personnalisée ===
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 " Les procs peuvent-ils être utilisés avec les instructions case en 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 fonctionne une déclaration de cas en Ruby et ce que vous pouvez en faire ".)
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.