#web-consoleの使い方
##エラーが発生させる方法
下記のようにRails4.2のプロジェクトでエラー出すとブラウザ上にconsoleが表示されます。
そのままUser.allしたり、ローカル変数にアクセスしたりできます。
def index
raise
@users = User.all
end
##consoleを使う方法
下のようにconsoleメソッドを呼んでもweb-consoleは起動してくれます。
def index
console
@users = User.all
end
#web-consoleのスコープ
##ローカル変数のスコープ
web-consoleのスコープ周りについてもう少し深く調べてみました。
下のようにブロック内でconsoleを呼ぶとweb-consoleではどの変数にアクセスできるか調べてみました。
def index
a = 1 # アクセス可能(1が入っている)
lambda {
console
b = 1 # アクセス可能(1が入っている)
}.call
lambda {
c = 1 # アクセス不可(undefined local variable or method エラー)
}.call
test
@users = User.all
end
private
def test
d = 1 # アクセス不可(undefined local variable or method エラー)
end
調べた結果は上のコメントの通りです。
consoleを呼んだ時点のスコープの変数にだけアクセスできるみたいです。
##consoleメソッドを複数回呼んだ場合
def index
a = 1 # アクセス可能(1が入っている)
console
lambda {
console
b = 1 # アクセス不可(undefined local variable or method エラー)
}.call
@users = User.all
end
上記のようにconsoleを2回呼んだ場合、1回目のスコープが有効になります。
2回目以降は無視されるようです。
##consoleとraiseを両方使った場合
def index
a = 1 # アクセス可能(1が入っている)
lambda {
console
b = 1 # アクセス不可(undefined local variable or method エラー)
}.call
raise
@users = User.all
end
上記の場合も変数「b」にはアクセスできませんでした。
例外が発生した場合はconsoleのスコープが無効になるようです。
#web-consoleのコード
コードを少しだけ見てみました。
controller_helpers.rb のコードは下記の通りです。
bindingメソッドでBindingオブジェクトを生成しています。
Bindingオブジェクトはローカル変数等を保持してくれるようなのでこれを使ってweb-consoleで変数にアクセスしているのだと思います。
def console(binding = nil)
@_console_binding = binding || ::Kernel.binding.of_caller(1)
end
view_helpers.rb のコードは下の通りです。
深くは追いかけてないのですが、controllerでconsoleを使ったなかったら直接レンダリングしているようです。
def console(console_binding = nil)
return unless request.remote_ip.in?(WebConsole.config.whitelisted_ips)
console_binding ||= binding.of_caller(1)
unless controller.console_already_rendered
@console_session = WebConsole::REPLSession.create(binding: console_binding)
controller.console_already_rendered = true
render('rescues/web_console')
end
end