【黒魔術】binding_of_caller gem でメソッド呼び出し元の binding を手に入れる
GitHub - banister/binding_of_caller: Retrieve the binding of a method's caller in MRI 1.9.2+
この gem を使うと、メソッド呼び出し元の binding で eval することができます。
binding とは
ローカル変数やオブジェクトを保持するクラスです。
def a x = 'Hello' b(binding) end def b(bi) puts bi.eval('x') end a # => Hello
binding を利用すると、このように a メソッドのスコープで任意のコードを実行することが出来ます。
ただし、この方法では binding を b メソッドの引数として渡してやらないと a のスコープを手に入れることが出来ません。当たり前ですね。
ですが、引数に渡すのはめんどくさいと思います。そこで、binding_of_caller gem を使います。
binding_of_caller gem
Install
$ gem install binding_of_caller
もしくは
### file: Gemfile gem 'binding_of_caller'
$ bundle install
使用例
require 'binding_of_caller' def a x = 'Hello' b end def b puts binding.of_caller(1).eval('x') end a # => Hello
先ほどのコードと違い、b メソッドには何も引数を渡していません。
ですが、b メソッドの中で binding#of_caller
を呼び出して、呼び出し元のメソッド(a)での binding を取得しています。
まあ、色々書いたわけですが、言いたいことは全部READMEにかかれているのでそっちを読んだほうがいいと思います。
ちなみに、READMEには
Recommended for use only in debugging situations. Do not use this in production apps.
だなんて書いてあります。