expect(1).to be 1 が成立するのが不思議だった

  • 1
    いいね
  • 3
    コメント

概要

RSpec の be マッチャーは何となく雰囲気で、いわゆる「参照一致」だと思っており、そうなら何故別変数のように見える 11 が一致するのかというのが不思議でした。

理由

beequal? を使って検証するものである。

Ref)
https://relishapp.com/rspec/rspec-expectations/v/3-5/docs/built-in-matchers/equality-matchers

expect(a).to be(b) # passes if a.equal?(b)


#equal? とは Object#equal? のことであり、以下の動作をする

お互いのObject#object_idが一致する かどうかを調べます。


Object#object_id

アクティブなオブジェクト間で 重複しない整数(object_id)が各オブジェクトにひとつずつ割り当てられています。

とのことだが、例外として、

TrueClass, FalseClass, NilClass, Symbol, Fixnum クラス のインスタンスなど Immutable(変更不可)なオブジェクトの一部は同じ内容ならば必ず同じ object_id になります。

とのことだった。

だから expect(1).to be 1 は同じ object_id を比較でき、成立する。

なお、そもそも expect(1).to be 1 は誤りなので

expect(1).to eq 1

と書くべきである。

同値が同object_idを持つのは、例外的な動作だから。

残った疑問

Immutable(変更不可)なオブジェクト

という文は、.frozen?true という意味と一緒なのだろうか?