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


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


1829
2018-06-04 01:18


origen


Respuestas:


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

Esto permite sofisticados 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.

diferente a switch declaraciones en muchos otros idiomas, Ruby's case no tiene caer a través, así que no hay necesidad de terminar cada when con un break. También puede especificar múltiples coincidencias en una sola when cláusula como when "foo", "bar".


2303
2018-06-04 01:22



case...when se comporta de forma inesperada al manejar clases. Esto se debe al hecho de que usa el === operador.

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

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

Esto significa que si quieres 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

Se imprimirá "No es una cadena".

Afortunadamente, esto se resuelve fácilmente. los === operador ha sido definido para que regrese true si lo usa con una clase y proporciona una instancia de esa clase como segundo operando:

Fixnum === 1 # => true

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

Hoy llegué a este problema mientras buscaba una respuesta, y esta era la primera página que aparecía, así que pensé que sería útil para otros en mi misma situación.


396
2018-04-17 15:20



Es hecho por caso en Ruby. Ver también 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

En alrededor de la página 123 (estoy usando Kindle) de The Ruby Programming Lanugage (1ra Edición, O'Reilly), dice el then palabra clave siguiendo el when las cláusulas pueden ser reemplazadas por una nueva línea o punto y coma (como en el if then else sintaxis). (Ruby 1.8 también permite un colon en lugar de then... Pero esta sintaxis ya no está permitida en Ruby 1.9.)


187
2018-06-04 01:20



    caso ... cuando

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

Con el 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 la cuestión ese kikito advierte


88
2017-07-05 13:19



Muchos lenguajes de programación, especialmente los derivados de C, tienen soporte para los llamados Switch Fallthrough. Estaba buscando la mejor manera de hacer lo mismo en Ruby y pensé que podría ser útil para otros:

En lenguajes tipo C, Fallthrough generalmente se ve 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, porque no es posible dejar 'a' ejecutar un bloque de código antes de caer a través de 'b' o 'c', pero en general me parece lo suficientemente similar como para ser útil de la misma manera.


64
2017-12-07 12:11



En Ruby 2.0, también puedes usar lambdas en case declaraciones, 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 sistema 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 sentencias case en Ruby 2.0?".)

O, 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 Ruby Case y qué puede hacer con ella".)


63
2017-08-01 00:04



Puede 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

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


47
2017-10-16 12:17



Si está ansioso por saber cómo usar una condición O en un caso de interruptor de Ruby:

Entonces, en una case declaración, una , es el equivalente de || en una if declaración.

case car
   when 'Maruti', 'Hyundai'
      # Code here
end

Muchas otras cosas que puede hacer con una declaración de caso de Ruby


29
2017-07-03 06:46