Identidad e igualdad
Parte de la sección Programación orientada a objetos del Journey de Ruby de Coddy. Lección 10 de 57.
Una variable contiene una referencia a un objeto, no el objeto en sí. Asignarla a otra variable copia la referencia, por lo que ambos nombres después hacen referencia al mismo objeto:
class Box
attr_accessor :count
def initialize
@count = 0
end
end
a = Box.new
b = a
b.count += 1
puts a.countSalida:
1equal? pregunta si dos referencias apuntan al mismo objeto, y object_id es el número único de cada objeto. Para tus propias clases, == hace lo mismo de forma predeterminada, por lo que dos objetos con los mismos valores no son iguales:
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_idSalida:
false
false
true
trueDefine == para comparar por valor. include?, index y delete en los arrays utilizan ==, por lo que después también encuentran objetos iguales. Comprueba primero la clase de other, para que comparar con un número o con nil devuelva false en lugar de fallar:
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))Salida:
true
false
true
falsedup crea un nuevo objeto con copias de las variables de instancia. Asignar un nuevo valor en la copia deja el original intacto, pero un arreglo o una cadena que haya dentro sigue compartiéndose entre ambos, porque solo se copió la referencia:
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.playersSalida:
Reds
["Ada"]Desafío
FácilCompleta la clase Point para que dos puntos con las mismas coordenadas sean iguales con ==, y que comparar un punto con cualquier otra cosa devuelva false. to_s devuelve (1, 2).
El código proporcionado lee puntos como líneas x,y. Para cada punto, imprime (1, 2) same as first: true o false; después mantiene una lista de puntos distintos usando include? y, finalmente, imprime distinct: 3 y si el primer punto es igual al texto "1,2".
Tu código debe ir en point.rb. main.rb contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
require_relative 'point'
# Código de entrada/salida suministrado: mantenlo tal 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 lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesVariables de instanciaMétodos y selfto_s e inspectRepaso: tarjeta de biblioteca4Encapsulación
Métodos privadosMétodos protegidosAsignadores privadosProtección del estadoRepaso: máquina expendedora7Polimorfismo y tipado pato
PolimorfismoTipado patoMétodos abstractoscase y clasesRepaso: métodos de pago2Accesores y self
Lectores y escritoresSetters personalizadosself en los métodosIdentidad e igualdadRepaso: lista de contactos5Herencia
SubclasesSobrescritura de métodosLlamar a superis_a? y ancestrosRepaso - Nómina del personal8Métodos especiales
Igualdad y hashMétodos de operadoresIndexación y adiciónColecciones personalizadasRepaso: fracciones11Proyecto: Gestión de biblioteca
Libros y miembrosPréstamo de librosPractica por tu cuenta: Compilador de Ruby online