You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Apologies if this is a duplicate. I've tried to find a dupe for this one (here in issues and in https://wiki.php.net/rfc but came up empty). There must be one as I can't be the first person to request this but here goes...
Request
PHP already has a wide variety of magic methods (https://www.php.net/manual/en/language.oop5.magic.php) and I think it would really benefit the language to add magic methods for comparison to allow class authors to override the comparator behaviour.
As a former python programmer I'll use the terms in that language (https://docs.python.org/2/reference/datamodel.html#special-method-names), I routinely found the following absolutely invaluable and now that I'm living in the PHP world, I'm finding the loss of these methods painful. The ones that I miss most are the comparison methods:
comparator method
semantics
__eq__($o):bool
$this == $o
__lt__($o):bool
$this < $o
__lte__($o):bool
$this <= $o
__gt__($o):bool
$this > $o
__gte__($o):bool
$this >= $o
__cmp__($o):int
returns {-1, 0, 1} (less than, equal to, greater than)
The operators (==, <, <=, >, >=) will call their corresponding comparator method if it exists, and if not, then it falls back to __cmp__($o) and if that isn't defined, then it falls back to it's default class comparison behaviour
Note: I'm not bothered about what the names are; PHP tends to be more long-hand than python for stuff like this (for instance, PHP uses __toString() whereas python uses __str__) so perhaps PHP should implement
__equalTo
__lessThan
__lessThanOrEqual
__greaterThan
__greaterThanOrEqual
__compareTo
I'm not bothered what they are called (although I do like python's brevity).
Reasoning
Without these methods, PHP forces class authors to implement comparison methods whose behaviour is likely to conflict with PHP's default comparison/identity logic, which is really bad because if you're comparing objects (for equivalence or for sorting) then
For those of us that need to do more than just class/property comparison/identity, PHP forces us to create multiple code/logic paths for comparison that conflict with each other and create one more method that developers have to remember to use (read - more time spent hunting bugs).
For instance, all three of these methods could have different results:
$a === $b;
$a == $b;
$a->equalTo( $b );
This is pretty much guaranteed to introduce bugs into software when the newbie comes into the team and starts throwing around "==" because the aren't aware that there's an equalTo() method.
As an aside, one of the most fundamental rules that I brow beat into my developers is "thou shalt have only ONE code path to perform any operation - duplication is the work of the devil" and I beat it into them regularly. So I can feel chills going down my spine when reading the above.
Having the ability to override the basic comparison methods (along with __repr__ and and even the logical ones too, so __and__ ,\ __or__, __xor__, etc) would also be awesome - more on that later).
Some Example Use Cases
1. Case insensitive string classes
class IString extends ...() {
...
public function equals($o) {
if ($o instanceof IString) return strtolower($this->value, $o->value);
elseif ($o instanceof ...)
{
...
} else { throw new UnsupportedComparisonException(self::class . ' cant compare to {$o::class}));
}
}
$a = new IString('A');
$b = new IString('a');
$a === $b # false
$a == $b # false
$a->equals($b) # true
But with the addition of a __equals method I can
2. Sorting
I can work around this by using things like __toString() to return a representation of the object (although I lose the ability to convert the object to a string - which is why python also has the\ __repr__ and __hash__ magic methods, which allow us to return a string representation of the object and a hash for the object, respectively).
But this is just a mess...
class IString {
public string $value;
public function __construct($v) { $this->value = $v; }
public function __toString() { return $this->value; }
}
class JClass {
public string $value;
public string $encoding;
public function __construct ($v) { $this->value = $v; $this->encoding = 'calculated'; }
public function __toString() { return "{$this->value}/{$this->encoding}"; }
}
$a = new IString('a');
$b = new JClass('B');
$arr = [ $a, $b ];
# print_r(sort($arr) + "\n"); // fails
usort($arr, fn ($a, $b) => strcmp(strval($a), strval($b)) );
print(json_encode($arr)); # [{"value":"B","encoding":"calculated"},{"value":"a"}]
And I'd need to reproduce the above ugliness every time I had to do any kind of comparison of the methods (ie - more "dual code path methods like equalTo, Sort, etc".
But given a simple magic comparator method (like the one in example #1) then code would simply be sort($arr); which is infinitely more readable and is going to be much less prone to have bugs. And when a new class is introduced into the comparison chain, it's super easy to just add it to the __compare()/ method to handle it.
Summary
I only provide two use cases, above, but I have had to use these methods almost every time I've created a data class in python. I find that creating these types of classes to be ugly in PHP (for the aforementioned reasons) and I seem to spend more time debugging code in different areas because some nugget-brain has forgotten that the "equalTo" or "compareTo" method exists.
PHP has already embraced magic methods so I think that adding these (comparators and equivalents of __repr__ and __hash__) would complement the existing methods perfectly.
The text was updated successfully, but these errors were encountered:
The RFC Tim mentioned is several years old, so plenty of time has passed since then to create and vote on another RFC.
And since the previous one was a large RFC that included overloads such as add and sub, if it were a proposal that only involved comparison, it is possible that we would get different results.
I don't think a GH issue is useful here. The issue has been proposed and rejected multiple times. If you'd like to pick the discussion back up, the mailing list + a new RFC is the place to do it. 🙂
Description
Apologies if this is a duplicate. I've tried to find a dupe for this one (here in issues and in https://wiki.php.net/rfc but came up empty). There must be one as I can't be the first person to request this but here goes...
Request
PHP already has a wide variety of magic methods (https://www.php.net/manual/en/language.oop5.magic.php) and I think it would really benefit the language to add magic methods for comparison to allow class authors to override the comparator behaviour.
As a former python programmer I'll use the terms in that language (https://docs.python.org/2/reference/datamodel.html#special-method-names), I routinely found the following absolutely invaluable and now that I'm living in the PHP world, I'm finding the loss of these methods painful. The ones that I miss most are the comparison methods:
The operators (==, <, <=, >, >=) will call their corresponding comparator method if it exists, and if not, then it falls back to __cmp__($o) and if that isn't defined, then it falls back to it's default class comparison behaviour
Note: I'm not bothered about what the names are; PHP tends to be more long-hand than python for stuff like this (for instance, PHP uses __toString() whereas python uses __str__) so perhaps PHP should implement
I'm not bothered what they are called (although I do like python's brevity).
Reasoning
Without these methods, PHP forces class authors to implement comparison methods whose behaviour is likely to conflict with PHP's default comparison/identity logic, which is really bad because if you're comparing objects (for equivalence or for sorting) then
For those of us that need to do more than just class/property comparison/identity, PHP forces us to create multiple code/logic paths for comparison that conflict with each other and create one more method that developers have to remember to use (read - more time spent hunting bugs).
For instance, all three of these methods could have different results:
This is pretty much guaranteed to introduce bugs into software when the newbie comes into the team and starts throwing around "==" because the aren't aware that there's an equalTo() method.
As an aside, one of the most fundamental rules that I brow beat into my developers is "thou shalt have only ONE code path to perform any operation - duplication is the work of the devil" and I beat it into them regularly. So I can feel chills going down my spine when reading the above.
Having the ability to override the basic comparison methods (along with __repr__ and and even the logical ones too, so __and__ ,\ __or__, __xor__, etc) would also be awesome - more on that later).
Some Example Use Cases
1. Case insensitive string classes
But with the addition of a __equals method I can
2. Sorting
I can work around this by using things like __toString() to return a representation of the object (although I lose the ability to convert the object to a string - which is why python also has the\ __repr__ and __hash__ magic methods, which allow us to return a string representation of the object and a hash for the object, respectively).
But this is just a mess...
And I'd need to reproduce the above ugliness every time I had to do any kind of comparison of the methods (ie - more "dual code path methods like equalTo, Sort, etc".
But given a simple magic comparator method (like the one in example #1) then code would simply be
sort($arr);
which is infinitely more readable and is going to be much less prone to have bugs. And when a new class is introduced into the comparison chain, it's super easy to just add it to the __compare()/ method to handle it.Summary
I only provide two use cases, above, but I have had to use these methods almost every time I've created a data class in python. I find that creating these types of classes to be ugly in PHP (for the aforementioned reasons) and I seem to spend more time debugging code in different areas because some nugget-brain has forgotten that the "equalTo" or "compareTo" method exists.
PHP has already embraced magic methods so I think that adding these (comparators and equivalents of __repr__ and __hash__) would complement the existing methods perfectly.
The text was updated successfully, but these errors were encountered: