Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

Ruby | Object | eql?

概要

Object#eql?(other) -> bool

詳細

Object の Hash の内容を比較して真偽値を返却する。

・Hash のキーの比較
・Array#uniq
・Set の同一性判定

などで利用される。
このメソッドをオーバーライドする場合は、
Object#hash も一緒にオーバーライドすること。

類似機能である

== は同値性のチェックだがより緩い(例えば 1 == 1.0 は真)
=== は同値性のチェックで、case 文用
equal? は同一性のチェックで、object_id を用いて比較

する。

サンプルコード
require 'set'

a = "hoge"
b = "hoge"

# String は eql? が同値チェックになっている
p a == b # => true
p a.eql? b # => true
p a.equal? b # => false

a = :hoge
b = :hoge

# Symbol は eql? が同値チェックになっていて、
# singleton のため object_id も同じになっている
p a == b # => true
p a.eql? b # => true
p a.equal? b # => true

class Person
  attr_reader :name, :age

  def initialize(name, age)
    @name, @age = name, age
  end

  def ==(other)
    @name == other.name && @age == other.age
  end
end

a = Person.new('tanaka', 25)
b = Person.new('tanaka', 25)

# 自作クラスはデフォルトだと eql? と equal? が同じ挙動
p a == b # => true
p a.eql? b # => false
p a.equal? b # => false
print Set[a, b].size, "\n" # => 2
print [a, b].uniq.size, "\n" # => 2
people_hash = {}
people_hash[a] = 1
people_hash[b] = 2
print people_hash.size, "\n" # => 2

class Person
  def eql?(other)
    @name == other.name && @age == other.age
  end

  def hash
    [@name, @age].hash
  end
end

# 自作クラスの eql?, hash をオーバーライドすると同値チェックを実現できる
p a == b # => true
p a.eql? b # => true
p a.equal? b # => false
print Set[a, b].size, "\n" # => 1
print [a, b].uniq.size, "\n" # => 1
people_hash = {}
people_hash[a] = 1
people_hash[b] = 2
print people_hash.size, "\n" # => 1

出力

$ ruby object_eql.rb
true
true
false
true
true
true
true
false
false
2
2
2
true
true
false
1
1
1