【问题标题】:Ruby - Determining a return's execution trace / originRuby - 确定返回的执行跟踪/来源
【发布时间】:2016-10-13 04:02:51
【问题描述】:

我希望可以在另一个方法中确定给定返回的原始类/方法/等。例如:

# 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 上搜索 ruby​​docs 和使用公共/私有方法并没有帮助。有谁知道可以吗?

【问题讨论】:

    标签: ruby methods nested return trace


    【解决方案1】:

    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)。这些将为您提供更多控制权,因为您可以获得堆栈跟踪项的组件,例如标签。

    【讨论】:

    • 感谢您调查此问题。在我上面的例子中使用你的建议:pry(main)&gt; args.send :caller =&gt; ["test.rb:23: in 'printit'", "test.rb:26: in '&lt;main&gt;'"]
    • 使用caller_locations 的相同打印输出。当使用外部类和方法时,我看不到通过此特定跟踪将类/方法传递到 args 的方法。
    • 对不起,我现在明白了……你说得对,caller 不会帮助你,因为参数在其产生的值传递给方法之前被评估。您可以改为传递一个块或 lambda,以便将评估推迟到方法内部,但这仍然无济于事,除非您检查该块或 lambda 的 Ruby 字节码。
    猜你喜欢
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多