We ran into an interesting bug today. We had code that looked like this:
foos.sum(&:amount) == expected_total
where foos is a collection that has an amount property that returns a Money, and expected_total is also a Money.
This works fine, except when foos is empty. In that case, the default value 0 (an Integer) is used, and as it turns out:
0 == Money.new(0, "USD") # => false
The fix is easy enough, just provide an explicit initial value:
foos.sum(Money.new(0, "USD"), &:amount) == expected_total
but this still seems like a very easy way for developers to shoot themselves in the foot when dealing with Money. I was wondering if Shopify (or others) have dealt with this issue before and have any recommendations for avoiding this issue.
One thought I had was a Rubocop rule that requires an explicit initial value for all #sum calls, but that seems overkill and annoying since it works fine when dealing with non-Money numerics.
We ran into an interesting bug today. We had code that looked like this:
where
foosis a collection that has anamountproperty that returns aMoney, andexpected_totalis also aMoney.This works fine, except when
foosis empty. In that case, the default value0(anInteger) is used, and as it turns out:The fix is easy enough, just provide an explicit initial value:
but this still seems like a very easy way for developers to shoot themselves in the foot when dealing with
Money. I was wondering if Shopify (or others) have dealt with this issue before and have any recommendations for avoiding this issue.One thought I had was a Rubocop rule that requires an explicit initial value for all
#sumcalls, but that seems overkill and annoying since it works fine when dealing with non-Moneynumerics.