Re: [RFC] User-defined object comparison
| From: | Rudolf Theunissen | Date: | Sun, 01 Jul 2018 18:45:03 +0000 |
| Subject: | Re: [RFC] User-defined object comparison | ||
| References: | 1 2 3 4 5 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-102549@lists.php.net to get a copy of this message | ||
>
> I think what I was suggesting is that if people in future want to overload
> the operators specifically, we would want to provide an overload for <=>
> that was separate from __compareTo, so that you could overload that without
> breaking things like sorting.
I think it would be confusing to have both, or to have <=> not be aligned
with __compareTo, because they are semantically equivalent. By overloading
<=>, you have to also override comparison. Separating those is a recipe for
confusion.
Apologies if this is covered in the RFC, but does that apply wherever they
> are used? For instance, what will the following code do?
> class SpaceStation {
> public $shape;
> public function __construct($shape='[]') {
> $this->shape = $shape;
> }
> public function __compareTo($other) {
> return new self($this->shape . '>=<' . $other->shape);
> }
> }
> $a = new SpaceStation;
> $b = new SpaceStation;
> $c = $a <=> $b; // Error? 0?
> echo $c->shape; // or will this echo '[]>=<[]'?
> $d = $a < $b; // Same result?
> $list = [$a, $b, $c, $d];
> sort($list); // Or will the error only be raised here?
When you use the
<=> operator, the return value is normalised to either
-1, 0 or 1 which is consistent with the current behaviour. So the object
you're returning in compareTo will be converted to an integer(1) which
will make $c be 1. Attempting to call echo $c->shape then
makes no
sense.
$a < $b will be false because according to your return of 1,
$a would
be greater.
Sorting would then consider the LHS to always be greater also.
One thing that your example brings up is that <=> is not exactly
equivalent to calling __compareTo directly, which would just return the
raw value. This is exciting because it's a new issue that I'll add to the
RFC for consideration. Ideally we would like the operator and the magic
method to behave exactly the same, but that doesn't seem like a viable
option because we wouldn't want to magically translate the return value of
a function you're calling directly. The only option then is to simply
advise that <=> will normalise the return value of __compareTo. I'm
personally okay with that behaviour if it means the convention of the
return value of <=> remains intact.