1

私は一種のベンチマーク ユーティリティのようなものを書いています。メソッドがどのコンテキストから呼び出されているかを簡単に知る方法があるかどうか知りたいです。例で説明しましょう:

module Foo
  my_method
  class Foo
    my_method
    def self.foo
       my_method
    end
    def foo
      my_method
    end
  end
end
Foo::Foo.foo
Foo::Foo.new.foo

理想的には、上記の場合、「my_method」は次のように出力します。

モジュール「Foo」の定義で呼び出される クラス「Foo」の定義で呼び出される クラスメソッド「foo」の実行中に呼び出される インスタンスメソッド「foo」の実行中に呼び出される

現在の「スコープ」またはコンテキスト (またはルビーがそれを呼び出すもの) への何らかの参照を取得できれば、これは簡単ですが、それが可能かどうかはわかりません。誰かが私を正しい方向に向けることができますか?

4

4 に答える 4

0

Kernel#set_trace_funcを使用すると、トレース手順を定義できます(デバッグ/プロファイリングを目的としています)。例えば:

class Foo
  def self.foo
  end

  def foo
  end
end

set_trace_func proc { |event, file, line, id, binding, classname|
  printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
}

Foo.foo
Foo.new.foo

プリント:

c-return foo.rb:11 set_trace_func   Kernel
    line foo.rb:13                    
    call foo.rb:2         foo      Foo
  return foo.rb:3         foo      Foo
    line foo.rb:14                    
  c-call foo.rb:14        new    Class
  c-call foo.rb:14 initialize BasicObject
c-return foo.rb:14 initialize BasicObject
c-return foo.rb:14        new    Class
    call foo.rb:5         foo      Foo
  return foo.rb:6         foo      Foo
于 2012-11-05T21:39:37.637 に答える
0

メソッド定義内では、 を使用します__callee__。モジュール内で直接、を使用しますModule.nesting

于 2012-11-05T23:52:54.713 に答える
0

解決

モジュール定義、クラス定義、および実行中のメソッド (クラスまたはインスタンス メソッド) 内のメソッドを検出することが唯一の要件である場合は、次のようなものを使用します。

def my_method
    if ( a = /^.*?:\d*:in `(.*)'$/.match( caller[0] ) )
        puts ( b = /^<(.*?):(.*?)>$/.match( a[1] ) ) ? 
            "Called in definition of #{b[1].capitalize} \"#{b[2]}\"" :
            "Called during run of #{(self.is_a? Class) ? 'class' : 'instance'} method \"#{a[1]}\""
    end
end

分析

callerスタック トレースを含むものを使用します。最初の正規表現は、次の呼び出し元の要素の構文を解析するだけです。

[file]:[line]:in `<[type]:[name]>'

モジュールとクラスの

[file]:[line]:in `[method]'

メソッド用。

したがって、最初の正規表現はその[file]:[line]:in部分を切り取ります。2 つ目は、<X:Y>パターンがあるかどうかを確認します。

X含まれている場合は、classまたはmoduleand を直接大文字にすることができY、クラスまたはモジュールの名前が含まれていることを意味します。

それ以外の場合は、メソッド名を直接取得し、それがインスタンスメソッドかオブジェクトメソッドかを確認するだけです。このためには、 を検査するだけselfです。それが a のインスタンスである場合はClass、クラス メソッドを呼び出しています。そうでない場合は、インスタンス メソッドを呼び出しています。

テスト

あなたの例では、次の出力が得られます

モジュール「Foo」の
定義で呼び出される クラス「Foo」の定義で呼び出さ
れる クラスメソッド「foo」
の実行中に呼び出される インスタンスメソッド「foo」の実行中に呼び出される

于 2013-04-13T17:51:58.823 に答える
0

これを試して:

Foo::Foo.method(:foo)
Foo::Foo.new.method(:foo)
于 2012-11-05T22:44:23.260 に答える