6
0

gem 'debug'ではスコープ内の変数を優先して参照する

Posted at

最近プロダクトコードの調査をしていたとき、'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コマンドでスコープ内の変数などを確認する

ことを学んだ出来事でした。

参考

6
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
6
0