when switch rails hacer estructura end condicionales ruby switch-statement conditional

rails - Cómo escribir una instrucción switch en Ruby



rails case when default (21)

¿Cómo escribo una declaración de cambio en Ruby?


caso ... cuando

Para agregar más ejemplos a la respuesta de Chuck :

Con parámetro:

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

Sin parámetro:

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

Por favor, tenga en cuenta el problema que advierte kikito.


¿No hay soporte para expresiones regulares en su entorno? Ej. Shopify Script Editor (abril, 2018):

[Error]: RegExp constante sin inicializar

Una solución que sigue una combinación de métodos ya cubiertos anteriormente here y 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

Usé or s en la declaración del método de clase desde || tiene mayor precedencia que .include? . Si eres un ruby-nazi , imagina que usé esto (item.include? ''A'') || ... (item.include? ''A'') || ... lugar prueba de repl.it


Como se indica en muchas de las respuestas anteriores, el operador === se usa bajo el capó en las declaraciones de caso / cuándo.

Aquí hay algunos datos adicionales sobre ese operador.

Operador de igualdad de casos: ===

Muchas de las clases incorporadas de Ruby, como String, Range y Regexp, proporcionan sus propias implementaciones del operador ===, también conocido como igualdad de casos, triple igual o triple calidad. 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 a" o "es miembro de" el 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).

String === "zen" # Output: => true Range === (1..2) # Output: => true Array === [1,2,3] # Output: => true Integer === 2 # Output: => true

El mismo resultado se puede lograr con otros métodos que probablemente sean los más adecuados para el trabajo, como is_a? y instancia_de?

Rango de Implementación de ===

Cuando se llama al operador === en un objeto de rango, devuelve verdadero si el valor de la derecha se encuentra dentro del rango de la izquierda.

(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

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á qué implementación del método === será Llamado, por lo que las posiciones del operando no son intercambiables.

Implementación Regexp de ===

Devuelve verdadero si la cadena de la derecha coincide con la expresión regular de la izquierda. / zen / === "practicar zazen hoy" # Salida: => verdadero # es similar a "practicar zazen hoy" = ~ / zen /

La única diferencia relevante entre los dos ejemplos anteriores es que, cuando hay una coincidencia, === devuelve true y = ~ devuelve un entero, que es un valor verdadero en Ruby. Volveremos a esto pronto.


Dado que switch case siempre devuelve un solo objeto, podemos imprimir directamente su resultado:

puts case a when 0 "It''s zero" when 1 "It''s one" end


Dependiendo de su caso, podría preferir utilizar un hash de métodos.

Si hay una larga lista de cuándo y 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.

# 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])


En Ruby 2.0, también puede usar lambdas en declaraciones de case , de la siguiente manera:

is_even = ->(x) { x % 2 == 0 } case number when 0 then puts ''zero'' when is_even then puts ''even'' else puts ''odd'' end

También puede crear sus propios comparadores fácilmente utilizando un Struct con un === personalizado

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

(Ejemplo tomado de " ¿Se pueden usar procs con declaraciones de casos en Ruby 2.0? ".)

O bien, con una clase completa:

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

(Ejemplo tomado de " Cómo funciona una declaración de un caso Ruby y qué se puede hacer con él ".)


He empezado a utilizar:

a = "secondcase" var_name = case a when "firstcase" then "foo" when "secondcase" then "bar" end puts var_name >> "bar"

Ayuda a compacta el código en algunos casos.



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 lenguajes similares a C, la caída suele ser así:

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; }

En Ruby, lo mismo se puede lograr de la siguiente manera:

case expression when ''a'', ''b'', ''c'' # Do something for a, b or c when ''d'', ''e'' # Do something else for d or e end

Esto no es estrictamente equivalente, ya que no es posible permitir que ''a'' ejecute un bloque de código antes de pasar a ''b'' o ''c'' , pero en general, me parece lo suficientemente similar para ser útil de la misma manera.


Multi-valor cuando y sin valor caso:

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

Y una solución de expresión regular aquí:

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


Puedes escribir expresiones de casos de dos maneras diferentes en ruby.

  1. Similar a una serie de declaraciones "si"
  2. Especifique un objetivo al lado del caso y cada cláusula "cuándo" se compara con el objetivo.

1er camino

age = 20 case when age >= 21 puts "display something" when 1 == 0 puts "omg" else puts "default condition" end

2ª vía

case params[:unknown] when /Something/ then ''Nothing'' when /Something else/ then ''I dont know'' end


Puedes hacer esto de una manera más natural,

case expression when condtion1 function when condition2 function else function end


Puedes usar expresiones regulares, como encontrar un tipo de cadena:

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

El case de Ruby usará el operando de igualdad === para esto (gracias @JimDeville). Información adicional está disponible en " Operadores Ruby ". Esto también se puede hacer usando el ejemplo de @mmdemirbas (sin parámetro), solo este enfoque es más limpio para este tipo de casos.


Ruby usa el case para escribir declaraciones de cambio.

Según los documentos de Ruby :

Las declaraciones de casos consisten en una condición opcional, que está en la posición de un argumento a case , y cero o más when cláusulas. La primera cláusula when para coincidir con la condición (o para evaluar la verdad booleana, si la condición es nula) "gana" y se ejecuta su stanza de código. El valor de la declaración de caso es el valor de la cláusula when éxito, o nil si no existe tal cláusula.

Una declaración de caso puede terminar con una cláusula else . Cada una when una declaración puede tener múltiples valores candidatos, separados por comas.

Ejemplo:

case x when 1,2,3 puts "1, 2, or 3" when 10 puts "10" else puts "Some other number" end

Versión más corta:

case x when 1,2,3 then puts "1, 2, or 3" when 10 then puts "10" else puts "Some other number" end

Y como este blog de Honeybadger describe Ruby Case;

Se puede utilizar con Ranges :

case 5 when (1..10) puts "case statements match inclusion in a range" end ## => "case statements match inclusion in a range"

Se puede utilizar con Regex :

case "FOOBAR" when /BAR$/ puts "they can match regular expressions!" end ## => "they can match regular expressions!"

Se puede utilizar con Procs y Lambdas :

case 40 when -> (n) { n.to_s == "40" } puts "lambdas!" end ## => "lambdas"

Además, se puede utilizar con tus propias clases de partidos:

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


Se hace por case en ruby. También vea este artículo en Wikipedia .

Citado

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

Otro ejemplo:

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

Alrededor de la página 123 (estoy usando Kindle) de The Ruby Programming Lanugage (1ª edición, O''Reilly), dice que la palabra clave " then sigue a las cláusulas when puede ser reemplazada por una nueva línea o punto y coma (como en la sintaxis if then else ). (Ruby 1.8 también permite dos puntos en lugar de then ... Pero esta sintaxis ya no está permitida en Ruby 1.9).


Se llama case y funciona como cabría esperar, además de muchas más cosas divertidas por cortesía de === que implementa las pruebas.

case 5 when 5 puts ''yes'' else puts ''else'' end

Ahora para un poco de diversión:

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

Y resulta que también puede reemplazar una cadena arbitraria if / else (es decir, incluso si las pruebas no involucran una variable común) con un case omitiendo el parámetro del case inicial y simplemente escribiendo expresiones donde la primera coincidencia es lo que usted desea. querer.

case when x.nil? ... when (x.match /''^fn''/) ... when (x.include? ''substring'') ... when x.gsub(''o'', ''z'') == ''fnzrq'' ... when Time.now.tuesday? ... end



case...when comporta un poco inesperadamente al manejar clases. Esto se debe al hecho de que utiliza el operador === .

Ese operador funciona como se espera con los literales, pero no con las clases:

1 === 1 # => true Fixnum === Fixnum # => false

Esto significa que si desea hacer un case ... when sobre la clase de un objeto, esto no funcionará:

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

Imprimirá "No es una cadena".

Afortunadamente, esto se resuelve fácilmente. El operador === se ha definido de modo que devuelva true si lo usa con una clase y proporciona una instancia de esa clase como el segundo operando:

Fixnum === 1 # => true

En resumen, el código anterior se puede arreglar eliminando .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

Encontré este problema 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.


Ruby usa la expresión de case 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 cláusula when con el objeto en la cláusula case utilizando el operador === . Por ejemplo, 1..5 === x , y no x === 1..5 .

Esto permite sofisticado when cláusulas 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 declaraciones de switch en muchos otros idiomas, el case de Ruby no tiene fall-through lo que no hay necesidad de terminar cada una con un break . También puede especificar varias coincidencias en una sola cláusula when "foo", "bar" como when "foo", "bar" .



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