views:

83

answers:

1

I am writing a Rails 3 generator, but things get a bit complicated so I would like to extract some code to put it in a separate file.

So I create a file in the generator folder, and within my generator file, I put at the top:

require 'relative/path/to/my/code.rb'

But when I launch the generator, it tells me that it can't find the file.

activesupport-3.0.0.rc/lib/active_support/dependencies.rb:219:in `require': no such file to load -- relative/path/to/my/code.rb (LoadError)

Does anybody know a work around ?

+1  A: 

It depends which Ruby version you are using.

In 1.8, it should work as you do. In 1.9 you should use require_relative.

You should also not add '.rb' at the end, this is not recommended.

The danger with a simple 'require' with a relative path is if this script is itself required by another, then the path will be relative to the first script called:

rootdir
  - main.rb
  - subdir1
    - second.rb
    - subdir11
      - third.rb

If main.rb is called, and then require second.rb (with 'subdir1/second'), and then you want to require third.rb with 'subdir11/third.rb', it will not work.

You could be relative to the first script (subdir1/subdir11/third.rb), but that is not a good idea. You could use __FILE__ and then make it an absolute path:

require File.expand_path('../subdir11/third.rb', FILE)

(the first .. is to get in the directory which contains the file) or

require File.dirname(FILE) + '/subdir11/third.rb'

But the most common practice is to reference it from the rootdir.

In a gem, you can assume the rootdir will be in the $LOAD_PATH (or you can add it yourself).

In Rails you can use require "#{RAILS_ROOT}/path" (rails2) or

require Rails.root.join('path') (rails3)

eregon
Why is the '.rb' not recommended ? If not specified, the require method will anyways try to find the '.rb' file, or a '.so' or a '.dll'.
subtenante
'recommended' is probably not the good word, indeed. But this is common practice and I never saw any code using it, except when there is both a shared library and a ruby script with the same name.Also, it looks pretty ugly ;)
eregon