1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

rails consoleでcase文が期待通りに動かない理由

Last updated at Posted at 2018-06-29

経緯

こんなcase文があるとします。
前提として、case文では渡されたオブジェクトとwhenに書かれているオブジェクトを === で評価します。

caseで変数のクラスを比較しようとすると上手く行かない

checker.rb
class Checker
  def check(object)
    case object
    when Book
      puts "これはBookです"
    else
      puts "わかりません"
    end
  end
end

今回使用するBookクラスはこんな感じだとします。

app/models/book.rb
# == Schema Information
#
# Table name: books
#
#  id              :integer          not null, primary key
#  created_at      :datetime
#  updated_at      :datetime
#

class Book < ApplicationRecord
end

そして、次のコマンドをrails consoleで実行していたとします。
僕はpryを使っています。

$ rails console

checker = Checker.new
book = Book.first
checker.check(book)
# これはBookです

そのあと、consoleでゴニョゴニョしていると突然先ほどの処理が期待通りに動かなくなりました。

checker = Checker.new
checker.check(book)
# わかりません
checker.check(book)
# わかりません
checker.check(book)
# わかりません

なんでやねん!

原因

原因は至ってシンプルで、consoleにいるときにファイルを編集した際に リロードしてしまったために、Bookクラスの#object_idが変わってしまった ためでした。

調査

こんな調査をしました。

まず、Bookクラスが読み込まれたらputsでわかるようにします。

book.rb
class Book
  puts "Bookを読み込みました"
end

rails consoleを実行すると、まずBookクラスが読み込まれるので、putsが出力されます。

$ rails console
# Bookを読み込みました

次に、先ほどの処理を実行します。この時、

checker = Checker.new
book = Book.first
checker.check(book)
# これはBookです

# object_idは同じ
book.class.object_id
=> 70296714581660
Book.object_id
=> 70296714581660

# 同一のオブジェクト
book.class == Book
=> true

しかし、この流れでリロードを実行すると、状況が変わります。

reload!
# Reloading...
=> true

# checker.rbを変更したからもう一回読み込むと想定
checker = Checker.new

checker.check(book)
# Bookを読み込みました
# わかりません

# object_idが違う
book.class.object_id
=> 70296714581660
Book.object_id
=> 70296942109640

# 同一のオブジェクトではなくなっている
book.class == Book
=> false

当たり前と言えば当たり前ですが、reload!を実行すると、その後Bookを呼んだタイミングで読み込まれるので仕込んだ Bookを読み込みました が出力されます。そうすると、rubyの#object_idが変わってしまうために、見かけ上では一緒でも、同一のオブジェクトとして認識されないということでした。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?