最近プロダクトコードの調査をしていたとき、'debug' gemについて理解していなくて戸惑ったので残しておこうと思います。
ことの発端
こんな感じのコードを調査中に見かけました。
同名のローカル変数とプライベートメソッドが定義されています。
レコード取得の条件に大きな違いはなさそうで、なぜメソッドのbarを使わないのか意図が分からずにデバッガを挟みました。
class HogesController < ApplicationController
def show
# debuggerをここに入れた
bar = Bar.where(...)
end
private
def bar
@bar ||= Bar.where(...)
end
end
上記の位置でbar
を実行すると、プライベートメソッドの値が確認できると期待していたのですが、実際に返ってきたのはnilでした。
(rdbg) bar
nil
(rdbg) self.bar
[#<Bar: 0x0000ffff8ae36d38 ...>, ...]
(rdbg) @bar
[#<Bar: 0x0000ffff8ae36d38 ...>, ...]
メソッドが参照できなかった理由
デバッガがスコープを理解しているため、スコープ内で定義したローカル変数bar
を見つけ、優先してその値を返します。
まだ評価されていないローカル変数でもスコープ内であれば参照できるため、ここではnilが返ってきました。
スコープ内で定義される変数などはi
/info
で確認ができます。
(rdbg) info # command
%self = #<HogesController:0x0000ffff8b81a318>
bar = nil
ローカル変数を確認したい場合はi l
or i locals
or i local_variables
インスタンス変数を確認したい場合はi i
or i ivars
or i instance_variables
で確認できます。
意図しない値が返ってきたら
-
defined?(bar)
で実行しているものが何者かを確認する -
info
コマンドでスコープ内の変数などを確認する
ことを学んだ出来事でした。
参考