Tengo la siguiente situación:

type = "stringX"
someArray = ["stringX", "string1", "string2"]

case type
when "stringA"
  puts "a"
when "stringB"
  puts "b"
when someArray.any? { |x| x.include?(type) }
  puts "x"
when "stringC"
  puts "c"
end

Lo que esperaba que sucediera es que pasaría por el case y una vez que evalúe el método .any? como verdadero (porque en sí mismo se evalúa como verdadero), puts " X". Sin embargo, eso no es lo que está sucediendo aquí, solo pasa por el resto de case y alcanza un raise en algún lugar debajo de eso.

Me pregunto qué está pasando aquí.

1
SystemShock 27 dic. 2016 a las 11:21

3 respuestas

La mejor respuesta

Usa la operadora *

value = "stringX"
some_array = ["stringX", "string1", "string2"]

case type
when "stringA"
  puts "a"
when "stringB"
  puts "b"
when *some_array # notice the * before the variable name!
  puts "x"
when "stringC"
  puts "c"
end

¿Como funciona esto?

when *some_array comprueba si value es un elemento en some_array

4
akuhn 27 dic. 2016 a las 08:32

Para este caso particular, uno debería usar la brillante respuesta de @akuhn

Si necesita poner cualquier condición aleatoria dentro de case, puede hacerlo usando Proc#===:

type = "stringX"
someArray = ["stringX", "string1", "string2"]

case type
when "stringA" then puts "a"
when "stringB" then puts "b"
#    ⇓⇓⇓⇓⇓⇓⇓⇓ HERE
when ->(type) { someArray.any? { |x| x.include?(type) } }
  puts "x"
when "stringC" then puts "c"
end
2
Aleksei Matiushkin 27 dic. 2016 a las 08:42

EDITAR: No eliminaré la respuesta, porque creo que puede haber algo que no sabías antes, pero no funciona para tu caso de uso. Para eso deberías mirar mudasob, fue la respuesta

No funciona de esta manera, porque básicamente la declaración del caso comparará el objeto dado con el objeto (s) pasado a when, de manera similar a esto:

if type == "stringA"
  # ...
elsif type == "stringB"
  # ...

Y así sucesivamente, a menos que use una declaración de caso vacía.

case
when type == "stringA"
# ...

Sin embargo, esto es similar a una declaración if elsif, por lo que realmente no se ve muy a menudo. Sin embargo, en su caso, podemos hacer uso de operador splat de Ruby

case type
when "stringA"
  puts "a"
when "stringB"
  puts "b"
when *someArray
  puts "x"
when "stringC"
  puts "c"

El enunciado del caso de Ruby puede tomar múltiples argumentos con when que funcionan como "o"

case "A"
when "B"
  puts "B"
when "C", "A"
  puts "C or A"
end
# => C or A

Y el operador splat desplegará su matriz:

p ["a", "b"]
# => ["a", "b"]

p *["a", "b"]
# => "a"
# => "b"

p "a", "b"
# => "a"
# => "b"
0
Ninigi 27 dic. 2016 a las 08:47