RSpec で to_a しなくても違うオブジェクト同士を比較できるのはなぜか?
RSpec で eq マッチャで Array と ActiveModel::DeprecationHandlingMessageArray などの内容を比較すると to_a などせずに比較できるのは、RSpec ではなく ActiveModel 側の仕様だった。
eq マッチャは actual と expected を #== で比較している。
この #== は RSpec でオーバーライドされているのかと思っていたが、そうではなかった。
テストコード中に tap をかまして source_location を見てみたら SimpleDelegator だった。
`ruby
expect(subject.errors:error.tap{pp _1.method(:==).source_location}).to eq(%w(エラーメッセージです。)) `
ActiveModel::DeprecationHandlingMessageArray の実装を見てみたら、SimpleDelegator を継承していた。
SimpleDelegator の #== の実装は以下。
まず #equal? で比較して、false の場合は #__getobj__ でオブジェクトの値を取得して、それと expected を比較しているのだとわかった。