Identidade e Igualdade
Parte da seção Programação orientada a objetos do Journey de Ruby da Coddy. Lição 10 de 57.
Uma variável armazena uma referência a um objeto, não o objeto em si. Atribuí-la a outra variável copia a referência, portanto ambos os nomes passam a se referir ao mesmo objeto:
class Box
attr_accessor :count
def initialize
@count = 0
end
end
a = Box.new
b = a
b.count += 1
puts a.countSaída:
1equal? verifica se duas referências apontam para o mesmo objeto, e object_id é o número exclusivo de cada objeto. Para suas próprias classes, == faz o mesmo por padrão, então dois objetos com os mesmos valores não são iguais:
class Point
attr_reader :x, :y
def initialize(x, y)
@x = x
@y = y
end
end
a = Point.new(1, 2)
b = Point.new(1, 2)
c = a
puts a == b
puts a.equal?(b)
puts a.equal?(c)
puts a.object_id == c.object_idSaída:
false
false
true
trueDefina == para comparar por valor. include?, index e delete em arrays usam ==, então também encontram objetos iguais. Verifique primeiro a classe de other, para que comparar com um número ou nil retorne false em vez de falhar:
class Point
attr_reader :x, :y
def initialize(x, y)
@x = x
@y = y
end
def ==(other)
other.is_a?(Point) && x == other.x && y == other.y
end
end
a = Point.new(1, 2)
puts a == Point.new(1, 2)
puts a == 5
puts [Point.new(0, 0), Point.new(1, 2)].include?(a)
puts a.equal?(Point.new(1, 2))Saída:
true
false
true
falsedup cria um novo objeto com cópias das variáveis de instância. Atribuir um novo valor à cópia não altera o original, mas um array ou uma string dentro dela ainda é compartilhado entre os dois, porque apenas a referência foi copiada:
class Team
attr_accessor :name, :players
def initialize(name)
@name = name
@players = []
end
end
a = Team.new("Reds")
b = a.dup
b.name = "Blues"
b.players << "Ada"
puts a.name
p a.playersSaída:
Reds
["Ada"]Desafio
FácilComplete a classe Point para que dois pontos com as mesmas coordenadas sejam iguais com ==, e comparar um ponto com qualquer outra coisa retorne false. to_s retorna (1, 2).
O código fornecido lê pontos como linhas no formato x,y. Para cada ponto, ele imprime (1, 2) same as first: true ou false, depois mantém uma lista de pontos distintos usando include? e, por fim, imprime distinct: 3 e se o primeiro ponto é igual ao texto "1,2".
Seu código deve ficar em point.rb. main.rb contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
require_relative 'point'
# Código de entrada/saída fornecido: mantenha-o como está
input = []
while (line = gets)
input << line.chomp
end
points = input.map { |line| Point.new(*line.split(",").map(&:to_i)) }
points.each { |pt| puts "#{pt} same as first: #{pt == points[0]}" }
distinct = []
points.each { |pt| distinct << pt unless distinct.include?(pt) }
puts "distinct: #{distinct.size}"
puts "equals text: #{points[0] == input[0]}"
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 LivrosPratique por conta própria: Compilador de Ruby online