O Módulo Comparable
Parte da seção Programação orientada a objetos do Journey de Ruby da Coddy. Lição 29 de 57.
O módulo integrado do Ruby Comparable fornece a uma classe os operadores <, <=, ==, >, >= e os métodos between? e clamp. Ele precisa de um método da classe: <=>, que retorna um número negativo, 0 ou um número positivo quando o objeto é menor, igual ou maior:
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))Saída:
true
true
trueNúmeros e strings já têm <=>, então uma classe geralmente delega a um de seus valores. A comparação de arrays funciona elemento por elemento, o que permite ordenar por vários campos de uma só vez:
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 > cSaída:
true
truesort, min e max também usam <=>, portanto objetos da classe podem ser ordenados sem um bloco. clamp mantém um valor entre dois outros:
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))Saída:
150g, 400g, 900g
900g
1000g<=> deve retornar nil quando o outro objeto não puder ser comparado. Em seguida, Comparable gera ArgumentError para < e retorna false para ==, em vez de falhar com um confuso NoMethodError:
def <=>(other)
return nil unless other.is_a?(Weight)
grams <=> other.grams
end
Weight.new(1) == 5 # false
Weight.new(1) < 5 # ArgumentError: comparison of Weight with 5 failedDesafio
FácilComplete a classe Weight. Weight.parse(text) lê 500g, 1.2kg ou 2lb (1 lb equivale a 453.6 g) e armazena os gramas. Inclua Comparable e defina <=> com base nos gramas. to_s retorna os gramas arredondados para um número inteiro, como 1200g.
O código fornecido analisa cada linha de entrada e, em seguida, imprime os pesos ordenados, o mais pesado, o mais leve, se o primeiro peso está entre 1 kg e 2 kg e o primeiro peso limitado a no máximo 1 kg.
Seu código deve ficar em weight.rb. main.rb contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
require_relative 'weight'
# Código de entrada/saída fornecido: mantenha-o como está
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"))}"
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação orientada a objetos
1Classes e Objetos
Trabalhando com ArquivosDefinindo ClassesVariáveis de InstânciaMétodos e selfto_s e inspectRevisão - Cartão da Biblioteca4Encapsulamento
Métodos privadosMétodos protegidosSetters privadosProtegendo o estadoRevisão - Máquina de venda automática7Polimorfismo e Duck Typing
PolimorfismoDuck TypingMétodos Abstratoscase e ClassesRevisão - Métodos de Pagamento2Acessores e self
Leitores e GravadoresSetters Personalizadosself nos MétodosIdentidade e IgualdadeRecapitulação - Lista de Contatos5Herança
SubclassesSobrescrita de métodosChamando superis_a? e ancestraisRevisão - Folha de pagamento da equipe8Métodos Especiais
Igualdade e hashMétodos de OperadoresIndexação e AdiçãoColeções PersonalizadasRevisão - Frações11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de Livros3Métodos e Variáveis de Classe
Métodos de ClasseVariáveis de Instância da ClasseConstantesMétodos de FábricaRevisão - Códigos de Cupom6Módulos e Mixins
Módulos e includeEstendendo ObjetosO Módulo ComparableO Módulo EnumerableRecapitulação - Liga EsportivaPratique por conta própria: Compilador de Ruby online