Re: [RFC] User-defined object comparison

From: 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.

« previous php.internals (#102549) next »