根据堆栈跟踪的内容触发Pry绑定

时间:2015-01-13 20:47:27

标签: ruby-on-rails ruby pry

我想在一个函数中启动一个Pry会话,但由于我正在研究的项目中有一些元编程,Pry会在很多我不感兴趣的环境中被触发。如何根据程序当前执行的堆栈跟踪触发pry?

类似的东西,

binding.pry if stacktrace.include? "function_name"

2 个答案:

答案 0 :(得分:2)

对于Ruby 2.0+,您可以使用Kernel#caller_locations来获取程序的当前堆栈跟踪。

来自the docs for Kernel#caller_locations

  

caller_locations(start = 1,length = nil)→array或nil

     

source caller_locations(range)→array或nil

     

返回当前执行堆栈 - 包含backtrace的数组   位置对象。

     

有关详细信息,请参阅Thread::Backtrace::Location

正如我们从文档中看到的,此方法返回一个Thread::Backtrace::Location个对象数组,您可以使用它们来确定是否调用binding.pryThread::Backtrace::Location提供了一个名为base_label的方法,该方法返回堆栈中当前位置的方法名称。您可以使用它来检查当前堆栈跟踪是否通过具有特定名称的方法运行。

用法示例:

def a
  caller_locations(0)
end
def b
  a
end
def c
  b
end

c.map(&:base_label)
#=> ["a", "b", "c", "<main>"]

所以在你的情况下,你会像这样使用它:

binding.pry if caller_locations.map(&:base_label).include? function_name

如果您使用的是旧版本的Ruby(&lt; 2.0),则Kernel#caller_locations不可用,您必须使用Kernel#caller代替:

  

调用者(start = 1,length = nil)→array或nil

     

来电者(范围)→数组或无

     

返回当前执行堆栈 - 包含字符串的数组   表单文件:行或文件:行:在`方法'。

     

可选的start参数确定初始堆栈的数量   要从堆栈顶部省略的条目。

     

第二个可选长度参数可用于限制数量   条目从堆栈返回。

     

如果start大于当前执行的大小,则返回nil   叠加。

     

您可以选择传递一个范围,该范围将返回包含的数组   指定范围内的条目。

def a(skip)
  caller(skip)
end
def b(skip)
  a(skip)
end
def c(skip)
  b(skip)
end
c(0)   #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10:in `<main>'"]
c(1)   #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11:in `<main>'"]
c(2)   #=> ["prog:8:in `c'", "prog:12:in `<main>'"]
c(3)   #=> ["prog:13:in `<main>'"]
c(4)   #=> []
c(5)   #=> nil

您会注意到Kernel#caller_locationsKernel#caller之间的唯一区别是Kernel#caller返回一个字符串数组,而不是Thread::Backtrace::Location个对象的数组。这意味着您必须使用正则表达式之类的方法来匹配方法名称,而不是像使用Kernel#caller_locations那样只使用Array#include?。在你的情况下:

binding.pry if caller.any?{|stack_entry| stack_entry =~ /in `#{function_name}'$/}

有关在Ruby中获取堆栈跟踪的更多信息,请参阅how to get a stack trace object in Ruby?

答案 1 :(得分:1)

尝试

binding.pry if caller.any?{|fn_name| fn_name.include?('function_name')}

参考:How to get a stack trace object in Ruby?