Re: [RFC] [Discussion] Support object type in BCMath
| From: | Rowan Tommins [IMSoP] | Date: | Sat, 06 Apr 2024 10:36:40 +0000 |
| Subject: | Re: [RFC] [Discussion] Support object type in BCMath | ||
| References: | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-122993@lists.php.net to get a copy of this message | ||
On 5 April 2024 19:30:24 BST, Jordan LeDoux <jordan.ledoux@gmail.com> wrote:
>A composed class
>does not somehow prevent the accidental error of mixing currencies, it just
>moves where that error would occur
It does not prevent someone accidentally *attempting* to mix currencies, but it absolutely prevents
that mistake leading to bogus values in the application, because the methods available can all
detect it and throw an Error.
If the class has a mixture of currency-aware methods, and methods / operator overloads inherited
from Number, you can end up getting nonsensical results instead of an Error.
>If you want an actual answer about how a Money class would actually work in
>practice, it would likely be something like this:
>
>```
>// $val1 and $val2 are instances of the Money class with unknown currencies
>$val1Currency = $val1->getCurrency();
>$val2Currency = $val2->getCurrency();
>$val1 = $val1->convertToCommonCurrency();
>$val2 = $val2->convertToCommonCurrency();
>// perform the necessary calculations using operators
>$answer = $answer->convertToCurrency($userCurrency);
>```
You have missed out the key section: how do you actually add the two numbers? The addition MUST
enforce the precondition that its operands are in the same currency; any other behaviour is
nonsensical. So the definition of that method must be on the Money class, not inherited from Number.
If the add() method on Number is final, you'll need to define a new method
$val1->addCurrency($val2). The existing add() method and operator overload will be inherited
unchanged, but calling them won't just be useless, it will be dangerous, because they can give
nonsensical results.
That's what makes composition the better design in this case, because the Money class can
expose only the methods that actually have useful and safe behaviour.
The fact that the composed class can't add its own operator overloads is unfortunate; but
allowing inheritance wouldn't solve that, because the inherited overloads are all wrong anyway.
Regards,
Rowan Tommins
[IMSoP]