Il modulo Comparable
Fa parte della sezione Programmazione orientata agli oggetti del percorso Ruby di Coddy. Lezione 29 di 57.
Il modulo integrato Comparable di Ruby fornisce a una classe gli operatori <, <=, ==, >, >= e i metodi between? e clamp. Richiede un metodo della classe: <=>, che restituisce un numero negativo, 0 o un numero positivo quando l’oggetto è rispettivamente minore, uguale o maggiore:
class Weight
include Comparable
attr_reader :grams
def initialize(grams)
@grams = grams
end
def <=>(other)
grams <=> other.grams
end
end
a = Weight.new(500)
b = Weight.new(1200)
puts a < b
puts a == Weight.new(500)
puts b.between?(a, Weight.new(2000))Output:
true
true
trueNumeri e stringhe hanno già <=>, quindi di solito una classe delega a uno dei suoi valori. Il confronto tra array funziona elemento per elemento, consentendo di ordinare in base a più campi contemporaneamente:
class Person
include Comparable
attr_reader :last, :first
def initialize(first, last)
@first = first
@last = last
end
def <=>(other)
[last, first] <=> [other.last, other.first]
end
end
a = Person.new("Ada", "Lovelace")
b = Person.new("Alan", "Turing")
c = Person.new("Byron", "Lovelace")
puts a < c
puts b > cOutput:
true
truesort, min e max usano anche <=>, quindi gli oggetti della classe possono essere ordinati senza un blocco. clamp mantiene un valore tra altri due:
class Weight
include Comparable
attr_reader :grams
def initialize(grams)
@grams = grams
end
def <=>(other)
grams <=> other.grams
end
def to_s
"#{grams}g"
end
end
list = [Weight.new(900), Weight.new(150), Weight.new(400)]
puts list.sort.join(", ")
puts list.max
puts Weight.new(5000).clamp(Weight.new(0), Weight.new(1000))Output:
150g, 400g, 900g
900g
1000g<=> dovrebbe restituire nil quando l'altro oggetto non può essere confrontato. Comparable quindi genera ArgumentError per < e restituisce false per ==, invece di fallire con un NoMethodError fuorviante:
def <=>(other)
return nil unless other.is_a?(Weight)
grams <=> other.grams
end
Weight.new(1) == 5 # false
Weight.new(1) < 5 # ArgumentError: confronto di Weight con 5 non riuscitoSfida
FacileCompleta la classe Weight. Weight.parse(text) legge 500g, 1.2kg o 2lb (1 lb corrisponde a 453.6 g) e memorizza i grammi. Includi Comparable e definisci <=> sui grammi. to_s restituisce i grammi arrotondati al numero intero più vicino, come 1200g.
Il codice fornito analizza ogni riga di input, poi stampa i pesi in ordine, il più pesante, il più leggero, indica se il primo peso è compreso tra 1 kg e 2 kg e stampa il primo peso limitato a un massimo di 1 kg.
Il tuo codice va inserito in weight.rb. main.rb contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
require_relative 'weight'
# Codice di input/output fornito: lascialo così com'è
input = []
while (line = gets)
input << line.chomp
end
weights = input.map { |line| Weight.parse(line) }
puts "sorted: #{weights.sort.join(", ")}"
puts "heaviest: #{weights.max}"
puts "lightest: #{weights.min}"
puts "first between 1kg and 2kg: #{weights[0].between?(Weight.parse("1kg"), Weight.parse("2kg"))}"
puts "first clamped: #{weights[0].clamp(Weight.parse("0g"), Weight.parse("1kg"))}"
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiVariabili d'istanzaMetodi e selfto_s e inspectRipasso - Tessera della biblioteca4Incapsulamento
Metodi privatiMetodi protettiSetter privatiProteggere lo statoRiepilogo - Distributore automatico7Polimorfismo e Duck Typing
PolimorfismoDuck TypingMetodi astratticase e classiRiepilogo - Metodi di pagamento10Pattern di progettazione Parte 2
Delegazione con ForwardablePattern DecoratorPattern BuilderPattern State2Metodi di accesso e self
Metodi di lettura e scritturaSetter personalizzatiself nei metodiIdentità e uguaglianzaRiepilogo - Elenco contatti5Ereditarietà
SottoclassiRidefinizione dei metodiChiamare superis_a? e antenatiRiepilogo - Paghe del personale8Metodi speciali
Uguaglianza e hashMetodi degli operatoriIndicizzazione e appendCollezioni personalizzateRiepilogo - Frazioni11Progetto: Gestione della biblioteca
Libri e iscrittiPrendere in prestito i libri3Metodi e variabili di classe
Metodi di classeVariabili di istanza della classeCostantiMetodi factoryRiepilogo - Codici coupon6Moduli e mixin
Moduli e includeEstendere gli oggettiIl modulo ComparableIl modulo EnumerableRiepilogo - Lega sportivaEsercitati da solo: Compilatore Ruby online