# Equatable

## Overview

Normally, to compare objects you'd use the comparison operator `==` or the identical operator `===`. Sometimes it can do the job, but most of the time it's not enough. In some cases, we'd like to control the way our object is compared. It'd be great if PHP allowed for operator overloading, but unfortunately, at the moment it's not possible. This is one of the main reasons why the type `Equatable` exist.

Types that implement the `Equatable<T>` interface can be compared for equality to other value using the `equals()` method. Thanks to the fact the `Equatable` type is a generic interface, you can decide to what type your object can be compared.

It can become very useful when designing eg. value objects. To ease dealing with the `Equatable` types the library defines several [functions](/jungi-common/functions.md).

```php
/** @implements Equatable<self> */
class Phone implements Equatable
{
    public function __construct(private string $value) {}
    
    public function equals(self $other): bool
    {
        return $this->value === $other->value;
    }
}

assert(true === (new Phone('(321) 456-1234'))->equals(new Phone('(321) 456-1234')));
assert(false === (new Phone('(321) 456-1234'))->equals(new Phone('(454) 456-1234')));
```

## Design decisions

Technically, the `Equatable` interface doesn't contain any method. The `equals()` method was defined using the phpdoc  `@method` tag. I also was considering an alternative version, but in the end I stuck to the phpdoc version. I'll show you and try to explain why I prefer the phpdoc version over this alternative one.

```php
/**
 * @template T
 */
interface Equatable
{
    /** 
     * @param T $other
     */
    public function equals($other): bool;
}
```

At first glance, it looks better, but:

* Types of this interface would be forced to accept a value of any type. Of course, we can specify a parameter type using the `@param` tag, but we'd need to always remember about it. PHP at runtime won't care if something was incorrectly passed to our `equals()` method, it'll simply allow it, thus we lose the runtime type check.
* The `equals()` method is locked for any API changes. In future PHP versions, there may be means to better express the `Equatable` interface. Who knows, maybe even generics ([RFC](https://wiki.php.net/rfc/generics)) will be implemented in very close future. With the phpdoc version, it'll be possible to adapt it, without breaking other people's code.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://piku235.gitbook.io/jungi-common/equatable.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
