58

can you do this in ruby? it seems to "miss" the cases with inequalities

 case myvar
 when  myvar < -5
    do somethingA
 when -5..-3
    do special_something_XX
 when -2..-1
    do special_something_YY
 when myvar == 0
    do somethingB
 when myvar > 0
    go somethingC
 end
Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
jpw
  • 18,697
  • 25
  • 111
  • 187

5 Answers5

116

You are mixing two different types of case statements:

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

case
when var == 1
   doSomething
when var < 12
   doSomethingElse
end
toolkit
  • 49,809
  • 17
  • 109
  • 135
28
   case myvar
     when  proc { |n| n < -5 }
        do somethingA
     when -5..-3
        do special_something_XX
     when -2..-1
        do special_something_YY
     when proc { |n| n == 0 }
        do somethingB
     when proc { |n| n > 0 }
        go somethingC
     end
   end
talha2k
  • 24,937
  • 4
  • 62
  • 81
9

I am not personally convinced that you wouldn't be better off with if statements, but if you want a solution in that form:

Inf = 1.0/0

case myvar
when -Inf..-5
  do somethingA
when -5..-3
  do special_something_XX
when -2..-1
  do special_something_YY
when 0
  do somethingB
when 0..Inf
  do somethingC
end

My preferred solution follows. Here the order matters and you have to repeat the myvar, but it's much harder to leave out cases, you don't have to repeat each bound twice, and the strictness (< vs <= rather than .. vs ...) is much more obvious.

if myvar <= -5
  # less than -5
elsif myvar <= -3
  # between -5 and -3
elsif myvar <= -1
  # between -3 and -1
elsif myvar <= 0
  # between -1 and 0
else
  # larger than 0
end
Peter
  • 127,331
  • 53
  • 180
  • 211
  • I personally think that what makes the second alternative clearer are the comments, not the fact that if-elsif is used instead of case-when. That said, I also prefer if-elsif, but just because it is shorter. – kikito Feb 25 '11 at 10:06
4
def project_completion(percent)
 case percent
  when  percent..25
    "danger"
  when percent..50
    "warning"
  when percent..75
    "info"
  when percent..100
    "success"
  else
   "info"
  end
end
webdevguy
  • 975
  • 10
  • 17
Majid Mushtaq
  • 319
  • 1
  • 3
  • 14
  • This way seems kind of hackish, and presumably leads to `percent` being compared against itself several times. `case` / `when percent <= 25` / ... seems better (less code/more efficient). It's not necessarily quite as clear that `percent` is the focus of the comparisons, but I think it's easy to see that by looking at the `when` expressions. – mwfearnley Jun 17 '20 at 11:23
3

Using infinity may help

case var
when -Float::INFINITY..-1
when 0
when 1..2
when 3..Float::INFINITY
end
Vadym Tyemirov
  • 8,288
  • 4
  • 42
  • 38