I sympathise greatly with this problem. Essentially it's that

  require 'foo/bar'

is tested against each of the directories in $:, the last of which is
usually "." - but actually what you want is it relative to the directory
which the file is in, not the directory which the user happened to be in
when they ran your application!

A simple solution might be something like this:

  $:.push File.dirname(File.expand_path(__FILE__))

Or perhaps replace the '.' in $: with an object which dynamically returns
this:

  class Mydir
    def self.+(rest)
      self.to_str + rest
    end
    def self.to_str
      File.dirname(File.expand_path(__FILE__))
    end
  end  

  $:.each_index {|i| $:[i] = Mydir if $:[i] == '.'}

Proviso: that seems to work, but is not heavily tested!

However I cannot see any real use for require '../foo/bar' meaning 'relative
to the directory in which the user happened to be when they ran your
program', rather than 'relative to the directory in which the script which
contains this require statement is located'. So perhaps this ought to be
the default for non-absolute paths.

Regards,

Brian.