Hacker News new | ask | show | jobs
by stakecounter 3900 days ago
Should Money.new(20, 'USD') == Money.new(2000, 'US Cents')?

Or Money.new(20, 'USD') == Money.new(125, 'CNY') when ExchangeRateManager.getExchangeRate('CNY', 'USD') == 0.16?

My point is that when performing these comparisons, it may be useful to use a more descriptive function like:

boolean currenciesHaveSameWorth(Money m1, Money m2)

And then a reader of the calling code might not have to look into the implementation to understand what the function is doing, whereas you definitely would when using == because == now means "whatever it's overridden to mean"

1 comments

> Should Money.new(20, 'USD') == Money.new(2000, 'US Cents')?

Like someone else pointed out in this thread, designing APIs require consistency and good taste.

If I had to implement this API you code above would evaluate to `ArgumentError unknown currency "US Cents"`.

> Or Money.new(20, 'USD') == Money.new(125, 'CNY') when ExchangeRateManager.getExchangeRate('CNY', 'USD') == 0.16?

Again, me designing this API, it wouldn't be equal. Why? For the same reason `1 != "1"`, if you cast them, yes they are equal, but implicit casting (aka weak typing) is not idiomatic in Ruby, it's possible, but very rare.

> boolean currenciesHaveSameWorth(Money m1, Money m2)

At this point you might as well do `m1 == m2.convert_to(m1.currency)`, because "HaveSameWorth" might mean many different things too.

> At this point you might as well do `m1 == m2.convert_to(m1.currency)`, because "HaveSameWorth" might mean many different things too.

I personally hate that last style because it's obvious that the "HaveSameWorth" relation is intended to be symmetric, and by writing it like m1 == m2.convert(...) you're prefering one side over the other. It looks bad for me :).

Also, in case of real-life objects it makes sense to spell out what do you mean by 'equality' (or 'equivalency'), and leave the default implementation to represent the philosophical concepts of "the same" and "equivalent to".

But you almost certainly are logically preferring one side over the other! You do usdValue == cadValye.convert_to(usdValue.curr) because one of those currencies is the one your transaction is working with (in this case, USD is your goal).