Ruby usa la caseexpresió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 whencláusula con el objeto en la casecláusula usando el ===operador. Por ejemplo, 1..5 === xy no x === 1..5.
Esto permite whenclá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 switchdeclaraciones en muchos otros idiomas, Ruby's caseno tiene fallos, por lo que no es necesario terminar cada uno whencon un break. También puede especificar múltiples coincidencias en una sola whencláusula como when "foo", "bar".
                 
                
                
                 
whenyreturnen la misma línea:when "foo" then "bar"switchdeclaraciones en muchos otros idiomas, Ruby'scaseNO tiene fallos, por lo que no hay necesidad de terminar cada unowhencon unbreak.then. Por favor, vea también las otras respuestas.case...whense 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 ... whenclase 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 regresetruesi 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
.classparte 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" endlos 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
caseen 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
thenpalabra clave que sigue a laswhencláusulas se puede reemplazar con una nueva línea o punto y coma (como en laif then elsesintaxis). (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
orMuchos 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
casedeclaraciones, 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
caseusará 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
casedeclaración, a,es el equivalente de||en unaifdeclaración.Consulte " Cómo funciona una declaración de caso Ruby y qué puede hacer con ella ".
fuente
Se llama
casey 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)
caseomitiendo elcaseparámetro inicial y simplemente escribiendo expresiones donde la primera coincidencia es lo que desea.fuente
Ruby usa el
casepara escribir declaraciones de cambio.Según la
casedocumentació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
whensy 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 casesiempre 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
caseexpresiones de dos maneras diferentes en Ruby:ifdeclaracionescasey cadawhenclá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/whendeclaraciones.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) === 3es 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 unacasedeclaració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é
ors 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 unawhencláusula. Actúa como||de unaifdeclaración, es decir, se hace un OR de comparación y no un Y la comparación entre las expresiones delimitadas de lawhencláusula. Vea la siguiente declaración de caso:xno es menor que 2, pero el valor de retorno es"apple". ¿Por qué? Porquexera 3 y desde',`` acts as an||, it did not bother to evaluate the expressionx <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 comparaxcon===, lo cual no es cierto, ya quexes 3.Para hacer una
&&comparación, tendrá que tratarcasecomo unif/elsebloque: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 unawhenclá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 methodCASO 'para main: Object) `. Como dijo @ sondra.kinsey, no puedes usar mayúsculas. Ruby pensará que es CONSTANTE.El
caseoperador de declaración es comoswitchen los otros idiomas.Esta es la sintaxis de
switch...caseen C:Esta es la sintaxis de
case...whenen Ruby:Por ejemplo:
Para más información ver el
casedocumentación.fuente