Ruby require 'file' and relative location

Bobby B picture Bobby B · Jul 15, 2010 · Viewed 34.5k times · Source

So I'm writing some rspec tests and I'm embarrassed at my lack of Ruby understanding.

I have a file structure that looks like the following:

  • GUI_Tests/Tests/test_spec.rb
  • GUI_Tests/windows_gui.rb
  • GUI_Tests/upload_tool.rb

when I run spec for the test_spec.rb file, I require the upload_tool file to be included like so:

spec -r ../upload_tool -fs test_spec.rb

Then, the upload_tool requires windows_gui.rb, like so:

require '../windows_gui'

My question is, why so I have to reference windows_gui.rb relative to test_spec.rb (requiring the ../) rather than the upload_tool.rb? This feels wrong to me, I'll want to use the upload_tool.rb out of context of the test specs, which means changing the requires each time.

Clearly I'm missing something, but if I don't reference relative to the test spec I get a file not found error.

Sorry for being so ignorant here, but I'm coming up empty handed. Any thoughts appreciated.

BB

Answer

Adrian picture Adrian · Jul 15, 2010

You don't. requires are relative to the current directory, which in your case was GUI_Tests/Tests. If you did this instead:

cd ..
spec -r upload_tool -fs Test/test_spec.rb

You would have to use this:

require 'windows_gui' # without '../'

The most common way to get around that problem is using File.dirname(__FILE__):

require File.join(File.dirname(__FILE__), '..', 'windows_gui')

NOTE: in Ruby 1.9.2 require changed it's defaults: Ruby: require vs require_relative - best practice to workaround running in both Ruby <1.9.2 and >=1.9.2