[ruby-list:50011] Re: メソッドの呼び出し元のインスタンスを得る方法
From:
Kunimi Ikeda <kunimi.ikeda@...>
Date:
2014-11-20 10:33:40 UTC
List:
ruby-list #50011
いけだです。
情報提供ありがとうございます。
教えて頂いたbinding_of_callerを使って、目的を達成できそうです。
実は呼び出し元のインスタンスそのものが欲しかったわけではなく、
呼び出し元のインスタンスのインスタンス変数が欲しかったので、
下記のように書けて良い感じです。
def a_method
binding.of_caller(1).eval('@val')
end
パフォーマンスについても、確かに遅い(自分のインスタンス変数の参照よりも50倍ほど遅い)
ですが、私の用途としては、わりと気にしなくても良いかな、という感じでした。
下記、参考までにベンチマークを掲載します。
$ ruby a.rb
user system total real
0.500000 0.000000 0.500000 ( 0.506377)
0.010000 0.000000 0.010000 ( 0.013879)
$ cat a.rb
#!ruby -Ku
require "benchmark"
require "binding_of_caller"
class A
def initialize
@val_a = 'val_a!!!'
end
def test_a1
b = B.new
b.test_b1
end
def test_a2
b = B.new
b.test_b2
end
end
class B
def initialize
@val_b = 'val_b!!!'
end
def test_b1
binding.of_caller(1).eval('@val_a')
end
def test_b2
@val_b
end
end
a = A.new
puts Benchmark::CAPTION
puts Benchmark.measure {
10000.times do
a.test_a1
end
}
puts Benchmark.measure {
10000.times do
a.test_a2
end
}
On 2014/11/20 16:10, 橋立友宏 wrote:
> 橋立と申します。
>
> binding_of_callerというgemとevalを組み合わせることで取得する、という方法を使ったことがあります。
> しかし、かなり重い動作になるので、テストコードやデバッグ用途等のパフォーマンス要件がシビアでないケースのみで使うのが良いと思います。
>
> https://github.com/banister/binding_of_caller
>
> サンプルはこんな感じになります。
>
> def a_method
> binding.of_caller(1).eval('self')
> end
>
>
> 2014年11月20日 11:57 Kunimi Ikeda <kunimi.ikeda@gmail.com>:
>
>> いけだと申します。
>>
>> 下記の環境を使用しています。
>> $ ruby -v
>> ruby 2.0.0p598 (2014-11-13 revision 48408) [x86_64-linux]
>>
>>
>> あるメソッドの呼び出し元のインスタンスを得る方法は無いでしょうか。
>>
>> 目的を達成できそうなGemとして下記のGemを見つけましたが、Ruby2.0.0には
>> インストールできませんでした。(説明文によるとRuby 1.9.1用のようです)
>> https://github.com/Asher-/sender
>>
>>