module Context

grosser.it/2009/07/01/getting-the-caller-method-in-ruby/ this is like parse_caller() in ActionMailer apparently

Public Class Methods

determine(skip=1, &block) click to toggle source

return [n, dirname, filename or context, line num, self, function]

# File lib/tarpaulin.rb, line 20
def self.determine(skip=1, &block)
  begin
    # cheat, just in case it is nil, rather than handling that special case for now
    # cuz it's always possible to call a func that takes a block without an actual block :(
    # i suppose i could raise an ExpectingBlock Error
    b = block.send(:binding)
    snarf = caller(0)[skip] # defaults to 1
    # [0] is us --- ["../y_ruby/c.rb:9:in `determine'",
    #err "caller(): #{snarf.inspect}"
    matched = /^(.+?)[:](\d+)(.*)$/.match(snarf) # +? non-greedy
    #err "matched /^(.+?)[:](\d+)(.*)$/: #{matched}"
    # the whole thing is matched[0]
    context = matched[1] # is file or (eval) or (irb) or ...
    line_no = matched[2].to_i
    three = matched[3]
    #err "context = matched[1]: #{context}"
    #err "line_no = matched[2]: #{line_no}"
    #err "three = matched[2]: #{three}"
    #err "three is empty?: #{three.length.zero?.inspect}"
    fn = nil
    unless three.length.zero?
      matched = /^:in `(.+?)'$/.match(three)
      #err "matched /^:in `(.+?)'$/: #{matched}"
      fn = matched[1]
      #err "fn = matched[1]: #{fn}"
    end
    first_letter = context[0]
    #err "first_letter = context[0]: #{first_letter}"
    case first_letter
      when 40 # _(_ we do not handle (irb) and (eval) and whatever else yet
        {:type => 0, :path => Dir.getwd, :location => context, :line_number => line_no, :self => eval("self", b), :function => fn}
        #return Dir.getwd + '/' + string
      when 47 # _/_ absolute
        {:type => 1, :path => File.dirname(context), :location => File.basename(context), :line_number => line_no, :self => eval("self", b), :function => fn}
        #return File.dirname(context) + '/' + string
      when 46 # _._ relative ... to what?! i suppose the working dir unless it was changed :( (need a per binding ENV?)
        {:type => 2, :path => File.expand_path(File.dirname(context), ENV['PWD']), :location => File.basename(context), :line_number => line_no, :self => eval("self", b), :function => fn}
        #return File.expand_path(File.dirname(context)) + '/' + string
      else # bare file name i guess unless something weird is happening
        {:type => 3, :path => File.expand_path(File.dirname(context), ENV['PWD']), :location => File.basename(context), :line_number => line_no, :self => eval("self", b), :function => fn}
        #raise NameError.new("odd name found in backtrace -- " + context)
    end # case
  end # begin
end