Ruby - 确定返回的执行跟踪/来源

时间:2016-06-12 18:44:18

标签: ruby methods nested return trace

我希望能够在另一种方法中确定给定回报的原始类/方法等。 E.g:

# 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的源类/方法。到目前为止,搜索rubydoc并使用args上的公共/私有方法进行搜索并没有帮助。有人知道这是否可能?

1 个答案:

答案 0 :(得分: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方法返回一个Thread :: Backtrace :: Location对象的数组(参见http://ruby-doc.org/core-2.3.1/Thread/Backtrace/Location.html)。这些将为您提供更多控制,因为您可以获得堆栈跟踪项的组件,例如label。