Rubyのオブジェクト比較
最近Rubyのオブジェクト比較について凡ミスを犯したので戒めのためにここに記します。
RspecのテストでオブジェクトがNewされたことをテストしたかったので以下のサンプルの
ようなテストを書いてみました。
class Hello @message def initialize(message: nil) @message = message end def self.greeting @message end end describe Hello do let(:hello) { Hello.new(message: 'Hello World!') } example 'initialize' do expect(hello).to eq Hello.new(message: 'Hello World!') end end
Newしているインスタンス同士を比較しているので一見通るようにみえるのですが実際は通りません。
実行してみると、Rspecが以下のようにエラーの原因を適切に返してくれました。
Failures: 1) Hello initialize Failure/Error: expect(hello).to eq Hello.new(message: 'Hello World!') expected: # got: # (compared using ==) Diff: @@ -1,2 +1,2 @@ -# +# # ./sample_spec.rb:16:in `block (2 levels) in ' Finished in 0.0289 seconds (files took 0.17197 seconds to load) 1 example, 1 failure Failed examples: rspec ./sample_spec.rb:15 # Hello initialize
オブジェクトidが違う=(違うオブジェクト)なので通らないということです。
同値性と同一性の違いですね。
同じ引数を渡してNewした上記のクラスは、同値ですが同一ではありません。
一致させるのであれば、==メソッドを再定義するという方法があります。
class Hello attr_accessor :message def initialize(message: nil) @message = message end def ==(obj) @message == obj.message end def self.greeting @message end end
Specが通りました。
Finished in 0.00125 seconds (files took 0.1751 seconds to load) 1 example, 0 failures
ちなみにRubyには以下のようにいくつかの同値、同一判定のメソッドがあります。
演算子 | 内容 |
---|---|
== | 同値かどうかの比較 |
=== | caseで使われる比較で通常は==の比較と同じだが、オブジェクトによって変わる |
equal? | 同一かどうかの比較 |
eql? | ハッシュの内部で同じキーかどうかを調べるために使われるメソッド |
eql?はハッシュ以外の場合にオブジェクトによって挙動がかわります。
例えばObjectクラスのeql?では、equal?と同じになっていますが、StringやArrayなどでは
メソッドが上書きされていて、値が同じかどうかの判定になります。
irb(main):004:0> Object.new.eql? Object.new => false irb(main):005:0> "abc".eql? "abc" => true irb(main):006:0> [1,2,3].eql? [1,2,3] => true
TAG
エンジニア
金子 将範 rubyist
新しいことや難しい課題に挑戦することにやりがいを感じ、安定やぬるい事は退屈だと感じます。 考えるより先に手が動く、肉体派エンジニアで座右の銘は諸行無常。 大事なのは感性、プログラミングにおいても感覚で理解し、感覚で書きます。
TAG
- Android
- AWS
- Bitrise
- CodePipeline
- Firebase
- HTML
- iOS
- IoT
- JavaScript
- KPI
- Linux
- Mac
- Memcached
- MGRe
- MGReのゆるガチエンジニアブログ
- MySQL
- PHP
- PICK UP
- PR
- Python
- Ruby
- Ruby on Rails
- SEO
- Swift
- TIPS
- UI/UX
- VirtualBox
- Wantedly
- Windows
- アクセス解析
- イベントレポート
- エンジニアブログ
- ガジェット
- カスタマーサクセス
- サーバ技術
- サービス
- セキュリティ
- セミナー・展示会
- テクノロジー
- デザイン
- プレスリリース
- マーケティング施策
- マネジメント
- ラボ
- リーンスタートアップ
- 企画
- 会社紹介
- 会社紹介資料
- 勉強会
- 実績紹介
- 拡張性
- 採用
- 日常
- 書籍紹介
- 歓迎会
- 社内イベント
- 社員インタビュー
- 社長ブログ
- 視察
- 開発環境