首页 > 解决方案 > 奇怪的未定义方法 [] 但调试时没有错误

问题描述

我已经在 rubyruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-darwin14]​​ 和(Rails 4.2.5.2)

  def log_method_backtrace
    backtrace = []
    (4..8).map do |i| # 4 because before is ... map, log_method_backtrace...
        b = caller[i][/\/(?:.(?!\/))+$/]
        b = b[1..-2] # *This is the error line
        b = b.sub(':in `', '#')
        backtrace << "#{b} <- "
    end
    log "(Method called from #{backtrace.join})"
  end

当我调用它时,它会抛出这个错误:

NoMethodError: undefined method `[]' for nil:NilClass from (pry):5:in `block in log_method_backtrace'

但是,如果我在该行中放置一个调试器断点(我正在使用 binding.pry),并运行同一行,它就可以工作。

标签: rubyruby-2.2

解决方案


caller是一个原生 Ruby 方法,它以字符串数组的形式返回当前执行堆栈。我遇到的问题是,因为我的代码在控制台中运行,其中一行是:

"(pry):7:in `<main>'"

所有其他行的文件名/行/方法名称格式为:

/...../gems/pry-0.9.12.6/lib/pry/pry_instance.rb:328:in `eval'

我使用的正则表达式[/\/(?:.(?!\/))+$/]预计会捕获文件名,因为该行没有它返回的文件名,nil并且b[-1..2]b`nil.

在我调试时,caller变量在binding.pry执行时间被替换,使代码工作。

这就是我修复代码以使其工作的方式:

  def log_method_backtrace
    backtrace = []
    (4..8).map do |i| # 4 because before is ... map, log_method_backtrace...
        line = caller[i]
        b = line[/\/(?:.(?!\/))+$/] || line
        b = b[1..-2]
        b = b.sub(':in `', '#')
        backtrace << "#{b} <- "
    end
    log "(Method called from #{backtrace.join})"
  end

推荐阅读