Ima Ima - 3 days ago 5
Ruby Question

Case statement and comparison with integers

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

Answer

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 help show what's going on in the case statement. The following is one alternative that I think reads better.

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