This is an old revision of the document!
Request for Comments: How to write RFCs
- Version: 1.0
- Date: 2010-09-30
- Author: Adam Harvey aharvey@php.net
- Status: Under Discussion
- First Published at: http://wiki.php.net/rfc/comparable
This RFC offers a Comparable interface which can be used to implement userspace ordering of objects.
Introduction
Many other languages offer the ability to provide a method on a class which will be used when instances of that class are compared via comparison or equality operators. For example, Java provides the Comparable interface, while Python provides the __cmp__ magic method.
Interface
Given the inspiration that PHP has drawn from Java in other areas of object orientation, the chosen API mirrors that of Java, with the exception of the Java-specific generic functionality. Expressed as a PHP interface, it would look like this:
<?php interface Comparable { public function compareTo($o); } ?>
Sample Code
A minimal class implementing this may look as follows:
<?php class FuzzyException extends Exception {} class Fuzzy implements Comparable { const TOLERANCE = 0.0001; public function __construct($value) { $this->value = (float) $value; } public function compareTo($value) { if (!$value instanceof Fuzzy) { throw new FuzzyException('Can only compare to other Fuzzy values'); } $diff = $this->value - $value->value; if ($diff > self::TOLERANCE) { return 1; } elseif ($diff < -self::TOLERANCE) { return -1; } return 0; } } $a = new Fuzzy(1.23); $b = new Fuzzy(2.34); $c = new Fuzzy(2.340000001); var_dump($a > $b); // prints bool(false) var_dump($a <= $b); // prints bool(true) var_dump($c == $b); // prints bool(true), since it's within the tolerance var_dump($c == 'foo'); // throws a FuzzyException ?>
Implementation
The patch below implements the Comparable interface within SPL in the same manner as the Countable interface. The changes to the Zend Engine are limited to the zend_operators.c file, and merely involve extending the zend_compare_objects() function to check if the first object implements the Countable interface, and if so, to call the compareTo() method, and updating compare_function() to call zend_compare_objects() when appropriate. Comparison cases not involving objects are unaffected, as are builds without SPL.