开发者

Implementing the 'case' statement in order to match multiple 'when' conditions

I am using Ruby on Rails 3 and I would like to use a case statement that even after matching a when statement can continue to checks other when statement until the last else.

For example

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!"

end

Is it possible in Ru开发者_JAVA技巧by? If so, how?


Most of the code I see coming from ruby is done with if elsif else but you can mimic switch logical expressions similar to other languages like this:

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

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

This came from this SO Question. Like I said this is usually done with if elsif else in ruby such as:

if my_number == "1"
   #do stuff when equals 1
elsif my_number == "e"
   #same thing here
else
   #default, no case found
end 


Ruby doesn't have any sort of fall-through for case.

One alternative be a series of if statements using the === method, which is what case uses internally to compare the items.

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

This has two glaring issues.

  1. It isn't very DRY: has_matched? = true is littered all over the place.

  2. You always need to remember to place var on the right-hand-side of ===, because that's what case does behind the scenes.

You could create your own class with a matches? method that encapsulates this functionality. It could have a constructor that takes the value you'll be matching against (in this case, var), and it could have an else_do method that only executes its block if its internal @has_matched? instance variable is still false.

Edit:

The === method can mean anything you want it to mean. Generally, it's a more "forgiving" way to test equivalency between two objects. Here's an example from this this page:

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

Essentially, when Ruby encounters case var, it will call === on the objects against which you are comparing var.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜