Su molti oggetti in ruby è possibile usare operatori di comparazione, ad esempio:
>> 5 <= 5.0 => true >> 4 > 4 => false >> "a" < "b" => true
non è certo una cosa strana, è possibile farlo in quasi tutti i linguaggi.
In ruby però gli operatori sono dei metodi come tutti gli altri, ed è quindi possibile definirne di propri nelle proprie classi, ad esempio così:
>> class Person >> attr_reader :name >> def initialize(name) ?> @name= name >> end >> def == other ?> name == other.name >> end >> end => nil >> p1=Person.new "joe" => #<Person:0xb7d2abac @name="joe"> >> p2=Person.new "joe" => #<Person:0xb7d26854 @name="joe"> >> p1 == p2 => true
ma facendo così abbiamo definito un solo metodo:
>> p1 < p2 NoMethodError: undefined method `<' for #<Person:0xb7d2abac @name="joe"> from (irb):57 from (null):0
e sarebbe una bella fatica dover implementare anche tutti gli altri metodi di comparazione.
Per fortuna esiste un Mixin chiamato Comparable che si preoccupa di definirli per noi.
Tutto quello che dobbiamo fare è definire un operatore chiamato <=> (spesso chiamato spaceship operator, per la somiglianza con un disco volante).
- 1, se
selfè maggiore dell’altro - 0 se sono uguali
- -1 se l’altro è maggiore di
self
notate come si possa facilmente riutilizzare uno starship operator esistente per implementarne di proprio. Verifichiamo che tutto funzioni:
>> p1=Person.new "joe" => #<Person:0xb7cfac40 @name="joe"> >> p1=Person.new "john" => #<Person:0xb7cf4084 @name="john"> >> p1=Person.new "joe" => #<Person:0xb7ced450 @name="joe"> >> p2=Person.new "john" => #<Person:0xb7ce8d4c @name="john"> >> p3=Person.new "james" => #<Person:0xb7ce3860 @name="james"> >> p1 != p3 => true >> p1 < p3 => false >> p1 > p3 => true >> p2 >= p3 => true
perfetto.
Il modulo definisce anche un utile metodo beetween?(min,max) per stabilire se un oggetto è in un intervallo.
Infine, se usate degli oggetti Comparable in un Array o in un altro oggetto che includa Enumerable, potrete approfittare dei metodi min(), max() e sort, che ovviamente usano <=> per poter funzionare in modo corretto.