rfc:comparable

This is an old revision of the document!


Request for Comments: 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.

Patch

rfc/comparable.1285854052.txt.gz · Last modified: 2017/09/22 13:28 (external edit)