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?
CodePudding user response:
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 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 a 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
CodePudding user response:
In fact there is no Range#sum
because it is inherited from Enumerable#sum
So (5..5).sum
it is the same as (5..5).to_a.sum
(5..5).to_a # => [5]
That's the reason
To fix it you can do something like this (change else
branch of your ternary operator to elsif
)
def get_sum(a, b)
if a < b
(a..b).sum
elsif a > b
(b..a).sum
end
end
get_sum(1, 2) # => 3
get_sum(2, 1) # => 3
get_sum(5, 5) # => nil
But in my opinion get_sum(5, 5) == 5
is more clear than nil
CodePudding user response:
the ternary operator has only two branches. if the condition is not truthy the latter is executed. there are no cases where no branches are executed (unless some error happens but that's another case).
you get nil only if you have only a branch and that's not executed. e.g.
def get_sum(a,b)
if a < b
(a..b).sum
end
end
for get_sum(5, 5)
this evaluates to nil