2016-06-12 6 views
0

別のメソッド内の特定のリターンの元のクラス/メソッド/などを判断することができます。例えば:のようなRuby - リターンの実行トレース/起点を特定する

# Ruby 

class Stringify 
    def fancy(words) 
    return ">> #{words}" 
    end 

    def boring(words) 
    return "- #{words}" 
    end 
end 

class Yarnify 
    def fancy(words) 
    return ">> #{words}" 
    end 

    def boring(words) 
    return "- #{words}" 
    end 
end 

def printit(*args) 
    puts args 
end 

printit(Yarnify.new.boring("Hello")) 
printit(Stringify.new.fancy("Hey")) 
printit(Stringify.new.boring("Hi")) 
printit(Yarnify.new.fancy("Heyo")) 

# Output: 
"- Hello" 
">> Hey" 
"- Hi" 
">> Heyo" 

## Desired trace 
def printit(*args) 
    puts args 
    puts "Originated from #{args.what_called.method} within #{args.what_called.class}." 
end 

printit(Yarnify.new.fancy("This is a return!")) 

## Output 
">> This is a return!" 
"Originated from fancy within Yarnify." 

argsの内容は、それがprintitメソッドに渡される前に実行しているようです。しかし、私は同じように見える複数の入力を動的にミックスするユースケースを持っているので、argsのソースクラス/メソッドをログに記録する必要があります。 argsでrubydocsを精練し、公開/秘密の方法で遊んでいることはこれまでのところ役に立たなかった。それが可能なら誰でも知っていますか?

答えて

0

callerお探しのものはありますか?これは、スタックトレースが含まれています

#!/usr/bin/env ruby 

require 'awesome_print' 

def foo 
    bar 
end 


def bar 
    baz 
end 


def baz 
    ap caller 
end 


foo 

=begin 
Outputs: 

[ 
    [0] "./caller.rb:11:in `bar'", 
    [1] "./caller.rb:6:in `foo'", 
    [2] "./caller.rb:20:in `<main>'" 
] 
=end 

はまた、スレッドの配列を返すcaller_locations方法がある::バックトレース:: Locationオブジェクトを(http://ruby-doc.org/core-2.3.1/Thread/Backtrace/Location.htmlを参照してください)。これらは、ラベルなどのスタックトレース項目のコンポーネントを取得できるため、より制御しやすくなります。

+0

問題を探していただきありがとうございます。上記の例の助言を参考にしてください: 'pry(main)> args.send:caller => [" test.rb:23: 'printit' "、 " test.rb:26: '

' " ] ' –

+0

' caller_locations'を使って同じ印字をします。クラスとメソッドが外部のクラスとメソッドが使用されたときにこの特定のトレースを通じて 'args'に渡されるクラス/メソッドを取得する方法はありません。 –

+0

申し訳ありません、私は今理解しています...あなたが正しいと言うと、呼び出し側は引数がその生成値がメソッドに渡される前に評価されるので、助けにならないでしょう。代わりにブロックまたはラムダを渡して、評価がメソッド内まで延期されるようにすることもできますが、ブロックまたはラムダのRubyバイトコードを検査しない限り、それでも実際には役に立ちません。 –

関連する問題