Understanding Ruby'S Load Paths

Understanding Ruby's load paths

Ruby's $LOAD_PATH will not include your lib directory by default (even though that's where the file you're running is located).

You can either tell the ruby interpreter to include it:

ruby -Ilib lib/processor.rb

Or you can add the lib folder to the load path:

$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'processor/mapper'
...

Understanding load path in Ruby

I have two solution.

% tree .
.
├── lib
│   └── dir1
│   └── dir2
│   ├── a.rb
│   └── b.rb
└── main.rb

% cat a.rb
def method_a
puts :execute_a
end

% cat b.rb
def method_b
puts :execute_b
end

No.1 add load path all sub directories

def add_load_path_recursive(dir)
Dir.glob(dir + "/**/*/").each do |dir|
$LOAD_PATH << File.expand_path(dir)
end
end

add_load_path_recursive "./lib"

require 'a'
require 'b'

method_a
method_b

No.2 require all 'rb' files (recursive)

def require_recursive(dir)
Dir.glob(dir + "/**/*.rb").each do |dir|
require File.expand_path(dir)
end
end

require_recursive "./lib"

method_a
method_b

How are $LOAD_PATH and $: different?

They are not. Try running this command:

$ ruby -e 'puts $LOAD_PATH'

which doesn't make shell expand $LOAD_PATH due to use of ' instead of ".

Adding a directory to $LOAD_PATH (Ruby)

I would say go with $:.unshift File.dirname(__FILE__) over the other one, simply because I've seen much more usage of it in code than the $LOAD_PATH one, and it's shorter too!

What does $: . do to Ruby's require path?

  1. $: is the variable that holds an array of paths that make up your Ruby's load path
  2. << appends an item to the end of the array
  3. . refers to the current directory

    1   2  3
    | | |
    V V V
    $: << "."

So you are adding the current directory to Ruby's load path

References:

  1. Can be found in the Execution Environment Variables section of of this page from The Pragmatic Programmers Guide

    An array of strings, where each string specifies a directory to be searched for Ruby scripts and binary extensions used by the load and require methods. The initial value is the value of the arguments passed via the -I command-line option, followed by an installation-defined standard library location, followed by the current directory (“.”)[Obviously this link is for an older version of Ruby as this is still in there]. This variable may be set from within a program to alter the default search path; typically, programs use $: << dir to append dir to the path.

  2. Can be found in the docs for array at ruby-doc.org.

    Append—Pushes the given object on to the end of this array. This expression returns the array itself, so several appends may be chained together.

How does Ruby's $LOAD_PATH get affected in other files when changed in one file?

as other pointed out already LOAD_PATH is global.
You should not be relying on tricks like this though. In your case the right thing to do is to use require_relative

Load path in Rails?

Yes, the first line is for Ruby itself (and $: too). The second one is very similar to the first one, but for ActiveSupport.

load_once_paths An array of paths from which Rails will automatically load from only once. All elements of this array must also be in load_paths.

load_paths An array of additional paths to prepend to the load path. By default, all app, lib, vendor and mock paths are included in this list.

So, if you need to reload your dependencies every new request, don't add them to the one of load_once_paths directory.

Why is the structure of my ruby project like this and why use load path?

As your app currently stands it wouldn't make any difference.

With a real project there would be many more files though and you would require them through lib/codebreaker.rb so that users of your library just need to require the one file.

You wouldn't want to duplicate that list of requires in env.rb, so your specs load lib/codebreaker.rb, just like any other user of your library.

How to set Ruby's load path externally

See the "Ruby and Its World" chapter from The Pickaxe Book, specifically the section on environment variables. Excerpt:

RUBYLIB 
Additional search path for Ruby programs ($SAFE must be 0).
DLN_LIBRARY_PATH
Search path for dynamically loaded modules.
RUBYLIB_PREFIX
(Windows only) Mangle the RUBYLIB search path by adding this
prefix to each component.

In the Ruby programming language, what is the name of $:

  • The canonical (english) name of the $: global is $LOAD_PATH.
  • As the name says, it is an Array of library search paths, i.e. an array of Strings representing all the folders where the interpreter will search libraries in (when it encounters a require "mylibrary" instruction)
  • It can be used with the same caution that has to be paid when dealing with globals. Actually, it is often used when writing test or demo scripts included in gems or libraries, so that the test modifies the load path in order to find the library under test before installing it (e.g. $: << "../lib" assuming the script is in a sibling of lib)
  • It is used by all canonical Ruby versions/implementation. Note though that the current directory . was part of $: on 1.8.x, and has been removed for security reasons on 1.9.x.
  • Docs is available on every Ruby primer (picaxe book, ruby docs site).


Related Topics



Leave a reply



Submit