Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Case statement and comparison with integers

Tags:

ruby

case

I'm a newbie with Ruby and I don't know why it behaves this way in this case statement:

def evaluate(number)
  case
  when number<0
    puts "#{number} is negative"
  when 0..50
    puts "#{number} is between 0 and 51"
  when 51..100
    puts "#{number} is between 51 and 100"
  else 
    puts "#{number} is greater than 100"

  number = gets.chomp.to_i

  puts evaluate(number)

when passing -4 for example it works but if I add number to the case

  def evaluate(number)
  case number
  when number<0 ...

then it interprets the negative value as if was an else and prints out is greater than 100

Is there a reason for that? I'de be very thankful if someone could help me out

like image 440
Ima Avatar asked Nov 30 '16 22:11

Ima


1 Answers

Try this.

 def evaluate(number)
   case number
   when -Float::INFINITY...0
     puts "#{number} is negative"
   when 0..50
     puts "#{number} is between 0 and 51"
   when 51..100
     puts "#{number} is between 51 and 100"
   else 
     puts "#{number} is greater than 100"
   end
 end

puts evaluate(-43)
 # -43 is negative
puts evaluate(0)
 # 0 is between 0 and 51
puts evaluate(27)
 # 27 is between 0 and 51
puts evaluate(100)
 # 100 is between 51 and 100
puts evaluate(9999)
 # 9999 is greater than 100

Alternatively, because case statements use === for comparisons, you could write

 def evaluate(number)
   case
   when number < 0
     puts "#{number} is negative"
   when (0..50) === number
     puts "#{number} is between 0 and 51"
   when (51..100) === number
     puts "#{number} is between 51 and 100"
   else 
     puts "#{number} is greater than 100"
   end
 end

which effectively is what is happening in the first case statement presented above.

See Range#===: "Returns true if obj [the argument] is an element of the range, false otherwise." In other words, (1..10) === numberis true if and only if (1..10).include?(number).

I'm not advocating this alternative; I presented it to help show what's going on in the case statement. The following is an alternative that is a bit shorter and perhaps reads better.

 def evaluate(number)
   suffix =
   case number
   when -Float::INFINITY...0 then "negative"
   when 0..50                then "between 0 and 51"
   when 51..100              then "between 51 and 100"
   else                            "greater than 100"
   end
   puts "#{number} is #{suffix}"
 end
like image 71
Cary Swoveland Avatar answered Sep 24 '22 23:09

Cary Swoveland