DEV Community

loading...

4 ways to clean ranged comparisons in Ruby conditionals

libsyz profile image Miguel Jimenez Updated on ・2 min read

What is the best way to go when we find conditionals that deal with ranges?

fruits = 0
if age > 5 && age < 10
        fruits += 100
elsif age >= 10 && age < 15
    fruits += 200
end     

One part of the problem is that there are way too many ways to express the conditions

# all these conditions are the same
# first
if age > 5 && age < 10
if 5 < age && 10 > age
if age > 5 && 10 < age
if 5 < age && age < 10
# second
elsif age >= 10 && age < 15
elsif age >= 10 && 15 > age
elsif 10 <= age && age < 15
elsif age => 10  && age < 15

A few tips that I find helpful:

1. No greater than >

You can make the boundaries of the range more readable if you limit yourself to the < operator.

fruits = 0
if 5 < age && age < 10 # 5 |---- age is here -----| 10
    fruits += 100
elsif 10 <= age && age < 15 # 10 |---- age is here -----| 15
    fruits += 200
end     

Llewelyn Falco has a nice blog post where he covers this technique in depth.

2. Use Range

Using Ruby ranges are a good way to represent the conditions, and using .. versus ... can act as a substitute for or

fruits = 0
if (6...10).include?(age) # 6 |---- age is here -----| 10
    fruits += 100
elsif (10...15).include?(age) # 10 |---- age is here -----| 15
    fruits += 200
end     

3. Use case statements

Took me a while to realise this, but when you use case statements, what you are really doing is comparing two things with the threequals operator ===

The cool thing about it is that when you use === with ranges, you are checking for inclusion within the range.

(1..5) === 2

#=> true

Which means we can write something like this

fruits = 0
case age
when 6...10
    fruits += 100
when 10...15
    fruits += 200
end

4. Use #between?

The #between method gives us an idiomatic way to resolve comparisons. Even if it does not work perfectly well for our example due to the mixed presence use of > and in both conditions, it's good to know we have this in the Ruby toolkit

fruits = 0
case age
if age.between?(6,10)
    fruits += 100
elsif age.between?(10,15)
    fruits += 200
end

Discussion

pic
Editor guide