Is require File.expand_path(..., __FILE__) the best practice?
Asked Answered
G

4

52

Is require File.expand_path(..., __FILE__) the best way to require other files within a project?

Ganley answered 1/12, 2010 at 15:12 Comment(3)
I'd +100 this if I could. It's something I wish I could do without.Coycoyle
Possible duplicate of https://mcmap.net/q/117561/-what-does-__file__-mean-in-rubyEssay
possible duplicate of Ruby: require vs require_relative - best practice to workaround running in both Ruby <1.9.2 and >=1.9.2Percolate
E
37

In Ruby 1.9.2 + require_relative is probably the more correct way to do it.

require was changed to not include your '.' directory for security reasons. require_relative was added to provide a local-file solution for modules relative to your calling script's path.

You can search here on StackOverflow, particularly in "What is require_relative in Ruby?", and the internets and find usage tricks and the why-for messages explaining how it came about.

Essay answered 1/12, 2010 at 15:16 Comment(1)
Also, "Ruby: require vs require_relative - best practice to workaround running in both Ruby <1.9.2 and >=1.9.2" is a great thread explaining this.Essay
P
7

In Ruby 2.x you can use Kernel#__dir__

Paludal answered 2/9, 2013 at 18:2 Comment(0)
A
3

Unless you modify $LOAD_PATH, which would be a good idea if you keep loading from the same directory structure, you are stuck doing it that way.

The way I've taken to doing it, to ensure things are as cross-platform as possible, is this:

require File.expand_path(File.join(*%w[ ... ]), File.dirname(__FILE__))

It's a little verbose, but it results in the shortest possible path and the least amount of syntax fluff in most cases.

A more specific example would be:

require File.expand_path(File.join(*%w[ .. lib example ]), File.dirname(__FILE__))

You can combine this with a modification to $LOAD_PATH to simplify things if you're loading a lot of files and do this:

$LOAD_PATH << File.expand_path(File.join(*%w[ .. lib ]), File.dirname(__FILE__))

require 'example'
Amerigo answered 1/12, 2010 at 15:17 Comment(0)
C
2

In Ruby 1.8.x, where you don't have require_relative in core, File.expand_path(...,__FILE__) won't work.

Suppose __FILE__ == "/home/yourname/foo.rb". File.expand_path("bar.rb",__FILE__) gives "/home/yourname/foo.rb/bar.rb.

What you want is File.expand_path("bar.rb",File.dirname(__FILE__)) which returns "/home/yourname/bar.rb"

You could also get require_relative from the backports gem.

Cassondra answered 1/12, 2010 at 15:31 Comment(2)
you can always do require File.expand_path("../baz.rb", __FILE__) to include baz.rb from foo.rb in the same directory.Hardtop
Following on from Matt's comment, I see that File.expand_path("../../lib/mygem.rb", __FILE__) is an actual example given in the 2.1.0 docs for expand_path. But that involves pretending a non-directory is a directory and then moving to its supposed parent! I'm baffled that the official docs would recommend such a deviant approach, and I wonder if it only works through some brittle side-effect of the implementation which could change behaviour in future versions. I think the dirname approach is much cleaner.Airline

© 2022 - 2024 — McMap. All rights reserved.