Menu
Coddy logo textTech

Identité et égalité

Fait partie de la section Programmation orientée objet du Journey Ruby de Coddy. Leçon 10 sur 57.

Une variable contient une référence vers un objet, et non l’objet lui-même. L’affecter à une autre variable copie la référence, de sorte que les deux noms font alors référence au même objet :

class Box
  attr_accessor :count

  def initialize
    @count = 0
  end
end

a = Box.new
b = a
b.count += 1
puts a.count

Résultat :

1

equal? vérifie si deux références pointent vers le même objet, et object_id est le numéro unique de chaque objet. Pour vos propres classes, == fait la même chose par défaut, donc deux objets ayant les mêmes valeurs ne sont pas égaux :

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_id

Résultat :

false
false
true
true

Définissez == pour comparer par valeur. include?, index et delete sur les tableaux utilisent ==, ils trouvent donc également les objets égaux. Vérifiez d’abord la classe de other, afin qu’une comparaison avec un nombre ou nil renvoie false au lieu d’échouer :

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))

Sortie :

true
false
true
false

dup crée un nouvel objet avec des copies des variables d’instance. Attribuer une nouvelle valeur à la copie laisse l’originale intacte, mais un tableau ou une chaîne de caractères qu’elle contient reste partagé entre les deux, car seule la référence a été copiée :

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.players

Sortie :

Reds
["Ada"]
challenge icon

Défi

Facile

Complétez la classe Point afin que deux points ayant les mêmes coordonnées soient égaux avec ==, et que la comparaison d’un point avec quoi que ce soit d’autre renvoie false. to_s renvoie (1, 2).

Le code fourni lit les points sous forme de lignes x,y. Pour chaque point, il affiche (1, 2) same as first: true ou false, puis conserve une liste de points distincts à l’aide de include? et affiche enfin distinct: 3 ainsi que le résultat indiquant si le premier point est égal au texte "1,2".

Votre code doit être placé dans point.rb. main.rb contient le code d’entrée/sortie fourni et ne peut pas être modifié.

Essayez vous-même

require_relative 'point'

# Code d'entrée/sortie fourni : le garder tel quel
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]}"
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation orientée objet

Entraînez-vous par vous-même : Compilateur Ruby en ligne