Two objects can store equal values while still being separate object instances.

object identity `equal?` checks whether two variables point to the same object; `==` can compare object values.

Object Identity

other_name
object_identity.rb
Replay: real traced execution (multi-file project)
class Badge
  attr_reader :name

  def initialize(name)
    @name = name
  end

  def ==(other)
    other.is_a?(Badge) && name == other.name
  end
end

other_name = "Ada"

first = Badge.new("Ada")
second = Badge.new(other_name)

puts "first=#{first.name}"
puts "second=#{second.name}"
puts "same_object=#{first.equal?(second)}"
puts "same_value=#{first == second}"
class Badge
  attr_reader :name

  def initialize(name)
    @name = name
  end

  def ==(other)
    other.is_a?(Badge) && name == other.name
  end
end

other_name = "Grace"

first = Badge.new("Ada")
second = Badge.new(other_name)

puts "first=#{first.name}"
puts "second=#{second.name}"
puts "same_object=#{first.equal?(second)}"
puts "same_value=#{first == second}"
class Badge
  attr_reader :name

  def initialize(name)
    @name = name
  end

  def ==(other)
    other.is_a?(Badge) && name == other.name
  end
end

other_name = "Matz"

first = Badge.new("Ada")
second = Badge.new(other_name)

puts "first=#{first.name}"
puts "second=#{second.name}"
puts "same_object=#{first.equal?(second)}"
puts "same_value=#{first == second}"
  1. other_name ← Ada

    1class Badge2  attr_reader :name34  def initialize(name)5    @name = name6  end78  def ==(other)9    other.is_a?(Badge) && name == other.name10  end11end1213other_name→ Ada = "Ada"  #@other_name="Grace", "Matz"1415first = Badge.new("Ada")16second = Badge.new(other_name)
  2. @name ← Ada

    pass 1 of 2
    4def initialize(nameAda)5  @name→ Ada = nameAda6end
  3. first ← ⟨Badge A @name="Ada"⟩

    15first→ ⟨Badge A @name="Ada"⟩ = Badge.new("Ada")16second = Badge.new(other_nameAda)
  4. @name ← Ada

    pass 2 of 2
    4def initialize(nameAda)5  @name→ Ada = nameAda6end
  5. second ← ⟨Badge B @name="Ada"⟩

    15first = Badge.new("Ada")16second→ ⟨Badge B @name="Ada"⟩ = Badge.new(other_nameAda)1718puts "first=#{first.nameAda}"19puts "second=#{second.nameAda}"20puts "same_object=#{first.equal?(second)false}"21puts "same_value=#{first⟨Badge A @name="Ada"⟩ == second⟨Badge B @name="Ada"⟩}"
    outputfirst=Ada
    second=Ada
    same_object=false
  6. def ==(other)

    8def ==(other⟨Badge B @name="Ada"⟩)9  other.is_a?(Badge)true && name == other.nameAda10end
  7. puts "same_value=#{first == second}"

    20puts "same_object=#{first.equal?(second)}"21puts "same_value=#{first⟨Badge A @name="Ada"⟩ == second⟨Badge B @name="Ada"⟩}"
    outputsame_value=true
  1. other_name ← Grace

    1class Badge2  attr_reader :name34  def initialize(name)5    @name = name6  end78  def ==(other)9    other.is_a?(Badge) && name == other.name10  end11end1213other_name→ Grace = "Grace"1415first = Badge.new("Ada")16second = Badge.new(other_name)
  2. @name ← Ada

    pass 1 of 2
    4def initialize(nameAda)5  @name→ Ada = nameAda6end
  3. first ← ⟨Badge A @name="Ada"⟩

    15first→ ⟨Badge A @name="Ada"⟩ = Badge.new("Ada")16second = Badge.new(other_nameGrace)
  4. @name ← Grace

    pass 2 of 2
    4def initialize(nameGrace)5  @name→ Grace = nameGrace6end
  5. second ← ⟨Badge B @name="Grace"⟩

    15first = Badge.new("Ada")16second→ ⟨Badge B @name="Grace"⟩ = Badge.new(other_nameGrace)1718puts "first=#{first.nameAda}"19puts "second=#{second.nameGrace}"20puts "same_object=#{first.equal?(second)false}"21puts "same_value=#{first⟨Badge A @name="Ada"⟩ == second⟨Badge B @name="Grace"⟩}"
    outputfirst=Ada
    second=Grace
    same_object=false
  6. def ==(other)

    8def ==(other⟨Badge B @name="Grace"⟩)9  other.is_a?(Badge)true && name == other.nameGrace10end
  7. puts "same_value=#{first == second}"

    20puts "same_object=#{first.equal?(second)}"21puts "same_value=#{first⟨Badge A @name="Ada"⟩ == second⟨Badge B @name="Grace"⟩}"
    outputsame_value=false
  1. other_name ← Matz

    1class Badge2  attr_reader :name34  def initialize(name)5    @name = name6  end78  def ==(other)9    other.is_a?(Badge) && name == other.name10  end11end1213other_name→ Matz = "Matz"1415first = Badge.new("Ada")16second = Badge.new(other_name)
  2. @name ← Ada

    pass 1 of 2
    4def initialize(nameAda)5  @name→ Ada = nameAda6end
  3. first ← ⟨Badge A @name="Ada"⟩

    15first→ ⟨Badge A @name="Ada"⟩ = Badge.new("Ada")16second = Badge.new(other_nameMatz)
  4. @name ← Matz

    pass 2 of 2
    4def initialize(nameMatz)5  @name→ Matz = nameMatz6end
  5. second ← ⟨Badge B @name="Matz"⟩

    15first = Badge.new("Ada")16second→ ⟨Badge B @name="Matz"⟩ = Badge.new(other_nameMatz)1718puts "first=#{first.nameAda}"19puts "second=#{second.nameMatz}"20puts "same_object=#{first.equal?(second)false}"21puts "same_value=#{first⟨Badge A @name="Ada"⟩ == second⟨Badge B @name="Matz"⟩}"
    outputfirst=Ada
    second=Matz
    same_object=false
  6. def ==(other)

    8def ==(other⟨Badge B @name="Matz"⟩)9  other.is_a?(Badge)true && name == other.nameMatz10end
  7. puts "same_value=#{first == second}"

    20puts "same_object=#{first.equal?(second)}"21puts "same_value=#{first⟨Badge A @name="Ada"⟩ == second⟨Badge B @name="Matz"⟩}"
    outputsame_value=false