0

I've defined this method on ruby ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-darwin14] and (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

When I call it it throw this error:

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

But if I place a debugger breakpoint (I'm using binding.pry) in that line, and run the same line it works.

Arnold Roa
  • 7,335
  • 5
  • 50
  • 69
  • 1
    can you show the code for the caller method please - it's apparently returning nil some of the time – Mark Nov 30 '19 at 12:46

1 Answers1

0

caller is a native Ruby method that returns the current execution stack as an array of strings. The problem I was having was because, as my code was running in the console one of the lines was:

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

All the other lines had a filename/line/method name format as:

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

The regular expresion that I was using [/\/(?:.(?!\/))+$/] was expected to capture the filename as the line had no a filename it returned nil and the b[-1..2] was throwing an error as b was `nil.

While I'm debugging the caller variable got replaced on the binding.pry execution time, making the code work.

This is how I fixed the code to make it work:

  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
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Arnold Roa
  • 7,335
  • 5
  • 50
  • 69