はじめに
今回はRubyにおける比較演算子==
と.equal
の違いについて簡単にまとめてみました。
タイトルを読んでもピンと来ない方には、ある程度意味のある記事になっていると思うので読んでもらえると嬉しいです。
対象読者
-
==
と.equal?
の違いを理解せずに使っている人 - 「同一性」「同値性」と言われてもピンと来ない人
結論
いきなりですが結論です。
==
と.equal?
の違いは「同値性を判定している」か、「同一性を判定している」かです。
...タイトルのままですね。
あまりにも説明になっていないので、以下から詳しく解説していきます。
そもそも「同一性」「同値性」とは
- 同一性:参照値が同じオブジェクトを指していること(*1)
- 同値性:オブジェクトが同じ値を持っていること(*1)
(*1 『独習Ruby』から引用)
を意味しています。
具体例を使って説明します。
array1 = ['a', 'b', 'c']
array2 = ['a', 'b', 'c']
array1 == array2 #=> true
array1.equal?(array2) #=> false
上記の変数、array1, array2はどちらも値として['a', 'b', 'c']が格納されています。
これらを==
で比較すると両者の値は等しいのでtrue
が返却されます。
しかし、.equal?
で比較するとfalse
が返却されます。
なぜなら、array1, array2の中身は同じでも、メモリ上は別の場所に作成された異なるオブジェクトだからです。つまり.equal?
は、両者の参照先のメモリが同じかどうかを判定しているのです。
別の言い方をすれば、同じobject_idかどうかを判定しているとも言えます。
補足
今回の==
と.equal?
はイミュータブルなオブジェクト(TrueClass, FalseClass, Integerなど)に対して使う場合、注意が必要です。
int1 = 1
int2 = 1
int1 == int2 #=> true
int1.equal?(int2) #=> true
上記のように、別々に生成されたオブジェクトであるint1
とint2
が同一のオブジェクトとして判定されています。
これはイミュータブルなオブジェクトの場合、複数の場所から参照されても破壊的操作が行われないため、同値のオブジェクトは同じobject_idが割り当てられる(同値のインスタンスが複数生成されない)という内部的な挙動によるものです。
ただあくまでも例外的な挙動なので、同一性を比較するか同値性を比較するかで==
と.equal?
を使い分けるのがいいと思います。