Why is the string ‘3’ not matched in a case statement with the range (‘0’…’10’)?

Ranges use cover? for case equality. So it is comparing '3' >= '0' && '3' < '10' which results in false because '3' < '10' #=> false. Strings are compared based on character values.

For a better understanding you might want to see a string as an array of characters:

['3'] <=> ['1', '0'] #=> 1 (first operand is larger than the second)

To solve the issue convert your case input to an integer and use integer ranges:

case 3 # or variable.to_i
when 0...10
  puts 'number is valid'
else
  puts 'number is invalid'
end

This works because integers are not compared based on character code, but on actual value. 3 >= 0 && 3 < 10 results in true.

Alternatively you could explicitly tell when to use the member? (or include?) method, by not passing a range, but a method instead.

case '3'
when ('0'...'10').method(:member?)
  puts 'number is valid'
else
  puts 'number is invalid'
end

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)