Реализация оператора 'case' для соответствия нескольким условиям 'when' - PullRequest
5 голосов
/ 07 марта 2011

Я использую Ruby on Rails 3 и хотел бы использовать оператор case, который даже после сопоставления с оператором when может продолжать проверять другие when statement до последнего else.

Например

case var
when '1'
  if var2 == ...
    ...
  else
    ...
    puts "Don't make nothig but continue to check!"
    # Here I would like to continue to check if a 'when' statement will match 'var' until the 'else' case
  end
when '2'
  ...
...
else
  put "Yeee!"

конец

Возможно ли это в Ruby? Если да, то как?

Ответы [ 2 ]

3 голосов
/ 07 марта 2011

Большая часть кода, который я вижу в ruby, выполняется с помощью if elsif else, но вы можете имитировать переключение логических выражений, аналогичных другим языкам, например:

case var
when 1
  dosomething
when 2..3
  doSomethingElse
end

case
when var == 1
   doSomething
when var < 12
   doSomethingElse
end

Это пришло из этого SO Вопрос.Как я уже говорил, обычно это делается с помощью if elsif else в рубине, например:

if my_number == "1"
   #do stuff when equals 1
elsif my_number == "e"
   #same thing here
else
   #default, no case found
end 
1 голос
/ 07 марта 2011

Ruby не имеет каких-либо препятствий для case.

Один альтернативный вариант - серия операторов if с использованием метода ===, который case использует для внутреннего использования.для сравнения предметов.

has_matched? = false

if '2' === var
  has_matched? = true
  # stuff
end

if '3' === var
  has_matched? = true
  # other stuff
end

if something_else === var
  has_matched? = true
  # presumably some even more exciting stuff
end

if !has_matched?
  # more stuff
end

У этого есть две вопиющие проблемы.

  1. Это не очень СУХОЙ : has_matched? = true засореноповсюду.

  2. Вы всегда должны помнить, чтобы поместить var справа от ===, потому что это то, что case делает за кулисами.

Вы можете создать свой собственный класс с помощью метода matches?, который инкапсулирует эту функциональность.Он может иметь конструктор, который принимает значение, с которым вы будете сопоставлять (в данном случае, var), и он может иметь метод else_do, который выполняет свой блок, только если его внутренняя переменная @has_matched? экземпляра все еще равна false.

Редактировать:

Метод === может означать все, что вы хотите, чтобы это значило.Как правило, это более «прощающий» способ проверить эквивалентность между двумя объектами.Вот пример из этой этой страницы :

class String
  def ===(other_str)
    self.strip[0, other_str.length].downcase == other_str.downcase
  end
end

class Array
  def ===(str)
    self.any? {|elem| elem.include?(str)}
  end
end

class Fixnum
  def ===(str)
    self == str.to_i
  end
end

По существу, когда Ruby встречает case var, он вызовет === для объектов , против которых высравниваем var.

...