Ruby usa la case
expresión en su lugar.
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 compara el objeto en la when
cláusula con el objeto en la case
cláusula usando el ===
operador. Por ejemplo, 1..5 === x
y no x === 1..5
.
Esto permite when
cláusulas sofisticadas como se ve arriba. Los rangos, las clases y todo tipo de cosas se pueden probar en lugar de solo la igualdad.
A diferencia de las switch
declaraciones en muchos otros idiomas, Ruby's case
no tiene fallos, por lo que no es necesario terminar cada uno when
con un break
. También puede especificar múltiples coincidencias en una sola when
cláusula como when "foo", "bar"
.
when
yreturn
en la misma línea:when "foo" then "bar"
switch
declaraciones en muchos otros idiomas, Ruby'scase
NO tiene fallos, por lo que no hay necesidad de terminar cada unowhen
con unbreak
.then
. Por favor, vea también las otras respuestas.case...when
se comporta un poco inesperadamente cuando maneja clases. Esto se debe al hecho de que utiliza el===
operador.Ese operador funciona como se esperaba con literales, pero no con clases:
Esto significa que si desea hacer una
case ... when
clase sobre un objeto, esto no funcionará:Imprimirá "No es una cadena o número".
Afortunadamente, esto se resuelve fácilmente. El
===
operador se ha definido para que regresetrue
si lo usa con una clase y proporciona una instancia de esa clase como el segundo operando:En resumen, el código anterior se puede solucionar eliminando
.class
:Encontré este problema hoy mientras buscaba una respuesta, y esta fue la primera página que apareció, así que pensé que sería útil para otros en mi misma situación.
fuente
.class
parte en Es interesante observar, gracias. Por supuesto, este es un comportamiento completamente apropiado (aunque podría ver cómo podría ser un error común pensar que se imprimiríaIt is a string
) ... está probando la clase de algún objeto arbitrario, no el objeto en sí. Así, por ejemplo:case 'hello'.class when String then "String!" when Class then "Class!" else "Something else" end
los resultados en:"Class!"
Esto funciona de la misma para1.class
,{}.class
, etc caída.class
, obtenemos"String!"
o"Something else"
para estos diversos valores.Se hace usando
case
en Ruby. Consulte también " Cambiar declaración " en Wikipedia.Citado:
Otro ejemplo:
Alrededor de la página 123 de The Ruby Programming Language (1st Edition, O'Reilly) en mi Kindle, dice que la
then
palabra clave que sigue a laswhen
cláusulas se puede reemplazar con una nueva línea o punto y coma (como en laif then else
sintaxis). (Ruby 1.8 también permite dos puntos en lugar dethen
, pero esta sintaxis ya no está permitida en Ruby 1.9).fuente
when (-1.0/0.0)..-1 then "Epic fail"
type = #{score}
cada línea, simplemente puedo copiar lo que hiciste. Mucho más elegante, también me gustan mucho los one-liners (si es posible)caso ... cuando
Para agregar más ejemplos a la respuesta de Chuck :
Con parámetro:
Sin parámetro:
Tenga en cuenta " Cómo escribir una declaración de cambio en Ruby " sobre el que advierte kikito.
fuente
or
Muchos lenguajes de programación, especialmente los derivados de C, tienen soporte para el llamado Switch Fallthrough . Estaba buscando la mejor manera de hacer lo mismo en Ruby y pensé que podría ser útil para otros:
En los lenguajes tipo C, la caída generalmente se ve así:
En Ruby, se puede lograr lo mismo de la siguiente manera:
Esto no es estrictamente equivalente, porque no es posible dejar
'a'
ejecutar un bloque de código antes de caer en'b'
o'c'
, pero en su mayor parte lo encuentro lo suficientemente similar como para ser útil de la misma manera.fuente
En Ruby 2.0, también puede usar lambdas en
case
declaraciones, de la siguiente manera:También puede crear sus propios comparadores fácilmente usando un Struct con un personalizado
===
(Ejemplo tomado de " ¿Se pueden usar procs con declaraciones de caso en Ruby 2.0? ").
O, con una clase completa:
(Ejemplo tomado de " Cómo funciona una declaración de caso Ruby y qué puede hacer con ella ").
fuente
Puede usar expresiones regulares, como encontrar un tipo de cadena:
Ruby's
case
usará el operando de igualdad===
para esto (gracias @JimDeville). Hay información adicional disponible en " Operadores de Ruby ". Esto también se puede hacer usando el ejemplo @mmdemirbas (sin parámetro), solo este enfoque es más limpio para este tipo de casos.fuente
Si está ansioso por saber cómo usar una condición OR en una caja de interruptor Ruby:
Entonces, en una
case
declaración, a,
es el equivalente de||
en unaif
declaración.Consulte " Cómo funciona una declaración de caso Ruby y qué puede hacer con ella ".
fuente
Se llama
case
y funciona como era de esperar, además de muchas más cosas divertidas, cortesía de las===
cuales implementan las pruebas.Ahora para divertirse:
Y resulta que también puede reemplazar una cadena arbitraria if / else (es decir, incluso si las pruebas no involucran una variable común)
case
omitiendo elcase
parámetro inicial y simplemente escribiendo expresiones donde la primera coincidencia es lo que desea.fuente
Ruby usa el
case
para escribir declaraciones de cambio.Según la
case
documentación:Ejemplo:
Versión más corta:
Y como " Declaración del caso de Ruby - técnicas avanzadas " describe a Ruby
case
;Se puede usar con rangos :
Se puede usar con Regex :
Se puede usar con Procs y Lambdas :
Además, puede usarse con sus propias clases de coincidencia:
fuente
Dependiendo de su caso, podría preferir utilizar un hash de métodos.
Si hay una larga lista de
when
sy cada uno de ellos tiene un valor concreto para comparar (no un intervalo), será más efectivo declarar un hash de métodos y luego llamar al método relevante del hash de esa manera.fuente
Como
switch case
siempre devuelve un único objeto, podemos imprimir directamente su resultado:fuente
Caso de valor múltiple cuando y sin valor:
Y una solución de expresión regular aquí:
fuente
case some_string, when /\d/, (stuff), when /[a-zA-Z]/, (stuff), end
(donde,
significa nueva línea)Puedes escribir
case
expresiones de dos maneras diferentes en Ruby:if
declaracionescase
y cadawhen
cláusula se compara con el objetivo.o:
fuente
Puedes hacer esto de una manera más natural,
fuente
Muchas respuestas geniales, pero pensé que agregaría un factoide. Si estás intentando comparar objetos (clases), asegúrate de tener un método de nave espacial (no una broma) o entender cómo se están comparando.
" Ruby Equality And Object Comparison " es una buena discusión sobre el tema.
fuente
<=>
, que se utiliza para devolver -1, 0, 1 o cero, dependiendo de si la comparación devuelve menor que, igual, mayor que o no comparable, respectivamente. La documentación del módulo comparable de Ruby lo explica.Como se indica en muchas de las respuestas anteriores, el
===
operador se utiliza bajo el capó encase
/when
declaraciones.Aquí hay información adicional sobre ese operador:
Operador de igualdad de casos:
===
Muchas de las clases integradas de Ruby, como String, Range y Regexp, proporcionan sus propias implementaciones del
===
operador, también conocido como "igualdad de casos", "triple igual" o "tres iguales". Debido a que se implementa de manera diferente en cada clase, se comportará de manera diferente según el tipo de objeto al que se llamó. En general, devuelve verdadero si el objeto de la derecha "pertenece" o "es miembro del" objeto de la izquierda. Por ejemplo, se puede usar para probar si un objeto es una instancia de una clase (o una de sus subclases).Se puede lograr el mismo resultado con otros métodos que probablemente sean los más adecuados para el trabajo, como
is_a?
yinstance_of?
.Implementación de Rango de
===
Cuando
===
se llama al operador en un objeto de rango, devuelve verdadero si el valor de la derecha cae dentro del rango de la izquierda.Recuerde que el
===
operador invoca el===
método del objeto de la izquierda. Entonces(1..4) === 3
es equivalente a(1..4).=== 3
. En otras palabras, la clase del operando de la izquierda definirá a qué implementación del===
método se llamará, por lo que las posiciones de los operandos no son intercambiables.Implementación de Regexp de
===
Devuelve verdadero si la cadena de la derecha coincide con la expresión regular de la izquierda.
La única diferencia relevante entre los dos ejemplos anteriores es que, cuando hay una coincidencia,
===
devuelve verdadero y=~
devuelve un entero, que es un valor verdadero en Ruby. Volveremos a esto pronto.fuente
fuente
Para obtener más información, consulte " Ruby: si ... si no, caso, a menos que ".
fuente
Empecé a usar:
Ayuda a compactar código en algunos casos.
fuente
Hash
, en lugar de unacase
declaración.¿No hay soporte para expresiones regulares en su entorno? Por ejemplo, Shopify Script Editor (abril de 2018):
Una solución alternativa que sigue una combinación de métodos ya cubiertos anteriormente aquí y aquí :
Usé
or
s en la declaración del método de clase ya que||
tiene mayor prioridad que.include?
. Si eres un rubí-nazi , imagina que usé esto(item.include? 'A') || ...
en su lugar. repl.it test.fuente
Es crítico enfatizar la coma (
,
) en unawhen
cláusula. Actúa como||
de unaif
declaración, es decir, se hace un OR de comparación y no un Y la comparación entre las expresiones delimitadas de lawhen
cláusula. Vea la siguiente declaración de caso:x
no es menor que 2, pero el valor de retorno es"apple"
. ¿Por qué? Porquex
era 3 y desde',`` acts as an
||, it did not bother to evaluate the expression
x <2 '.Puede pensar que para realizar un AND , puede hacer algo como esto a continuación, pero no funciona:
No funciona porque se
(3 && x > 2)
evalúa como verdadero, y Ruby toma el valor Verdadero y lo comparax
con===
, lo cual no es cierto, ya quex
es 3.Para hacer una
&&
comparación, tendrá que tratarcase
como unif
/else
bloque:En el libro Ruby Programming Language, Matz dice que esta última forma es la forma simple (y que se usa con poca frecuencia), que no es más que una sintaxis alternativa para
if
/elsif
/else
. Sin embargo, si se usa con poca frecuencia o no, no veo ninguna otra forma de adjuntar múltiples&&
expresiones para unawhen
cláusula dada .fuente
if...elsif
? Parece que estás tratando de mezclar una declaración de caso y una condición. ¿Por qué? Simplemente ponga el condicional dentro del bloque when, por ejemplo.when 3; ( x < 2 ) ? 'apple' : 'orange'
Podemos escribir una declaración de cambio para múltiples condiciones.
Por ejemplo,
fuente
case
,when
,end
) Entre mayúsculas y minúsculas y no pueden estar en mayúsculas como este.NoMethodError (undefined method
CASO 'para main: Object) `. Como dijo @ sondra.kinsey, no puedes usar mayúsculas. Ruby pensará que es CONSTANTE.El
case
operador de declaración es comoswitch
en los otros idiomas.Esta es la sintaxis de
switch...case
en C:Esta es la sintaxis de
case...when
en Ruby:Por ejemplo:
Para más información ver el
case
documentación.fuente