Search code examples
rubyconditional-operator

Why is this method not returning nil when a and b are equal?


This method should return the sum of all numbers between a and b (not ordered) and should return a or b if they are equal.

def get_sum(a,b)
  a < b ? (a..b).sum : (b..a).sum
end

I'm curious as to why this method doesn't return nil when a and b are equal. The ternary operator takes care of the condition where a is less than or greater than b so I'm tempted to add return a if a==b before the ternary to test if they are equal but it appears it's not necessary.

For example, if a=5 and b=5 then the value returned is 5. Could someone explain why this is please?


Solution

  • This is just how the < operator (or rather method) works.

    a < b

    It returns true if a is less than b, otherwise it returns false.

    Therefore 5 < 5 returns false.

    By writing a..b you create a Range object Range.new(a, b), which starts at a and goes up to and including b. Afterwards you call the sum method on this object.

    Since the range 5..5 goes from 5 to and including 5, when you convert it to an array you get:

    (5..5).to_a #=> [5]
    

    And the sum method adds all numbers which are within this range. And since this range includes a single number 5, the result of this operation is 5.

    (5..5).sum #=> 5
    

    Your method could be written more concisely

    def get_sum(a, b)
      (a < b ? a..b : b..a).sum
    end
    

    To make it return 0 when a and b are the same, you could use an exclusive range with three dots ....

    def get_sum(a, b)
      (a < b ? a...b : b...a).sum
    end
    
    get_sum(5, 5) #=> 0
    get_sum(5, 6) #=> 5
    get_sum(5, 7) #=> 11