# Ruby 1.9's require_relative.

if defined?(RubyVM) && RUBY_DESCRIPTION.start_with?('ruby 1.9.2frame')
  require 'thread_frame'
end

module RequireRelative
  def abs_file
    if defined?(RubyVM::ThreadFrame)
      RubyVM::ThreadFrame.current.prev.source_container[1]
    elsif defined?(Rubinius) && "1.8.7" == RUBY_VERSION
      scope = Rubinius::StaticScope.of_sender
      script = scope.current_script
      if script
        script.data_path
      else
        nil
      end
    else
      file = caller.first.split(/:\d/,2).first
      if /\A\((.*)\)/ =~ file # eval, etc.
        nil
      end
      File.expand_path(file)
    end
  end
  module_function :abs_file
end
  
if RUBY_VERSION.start_with?('1.9')
  # On 1.9.2 platforms we don't do anything.
elsif defined?(Rubinius) && '1.8.7' == RUBY_VERSION
  module Kernel
    def require_relative(suffix)
      # Rubinius::Location#file stores relative file names while
      # Rubinius::Location#scope.current_script.data_path stores the
      # absolute file name. It is possible (hopeful even) that in the
      # future that Rubinius will change the API to be more
      # intuitive. When that occurs, I'll change the below to that
      # simpler thing.
      scope = Rubinius::StaticScope.of_sender
      script = scope.current_script
      if script
        require File.join(File.dirname(script.data_path), suffix)
      else
        raise LoadError "Something is wrong in trying to get relative path"
      end
    end
  end
elsif (RUBY_VERSION.start_with?('1.8') && 
       (RUBY_COPYRIGHT.end_with?('Yukihiro Matsumoto')) ||
       RUBY_ENGINE == 'jruby')
  def require_relative(suffix)
    file = caller.first.split(/:\d/,2).first
    if /\A\((.*)\)/ =~ file # eval, etc.
      raise LoadError, "require_relative is called in #{$1}"
    end
    require File.join(File.dirname(file), suffix)
  end
end
  
# demo
if __FILE__ == $0
  file = RequireRelative.abs_file
  puts file
  require 'tmpdir'
  dir = 
    if RUBY_VERSION.start_with?('1.8') && 
        RUBY_COPYRIGHT.end_with?('Yukihiro Matsumoto')
      puts "Note: require_relative doesn't work with Dir.chdir as it does on Rubinius or 1.9.2-head-nframe"
      '.'
    else
      Dir.tmpdir
    end
  Dir.chdir(dir) do 
    rel_file = File.basename(file)
    cur_dir  = File.basename(File.dirname(file))
    ['./', "../#{cur_dir}/"].each do |prefix|
      test = "#{prefix}#{rel_file}"
      puts "#{test}: #{require_relative test}"
      puts "#{test}: #{require_relative test} -- should be false"
    end
  end
end
