Path (Linux), LOAD_PATH (Ruby) and autoload_paths (Rails).
Coming into Rails development, you may stumble upon 3 different paths:
Linux
[$PATH
environmental variable]
~❯ echo $PATH
/home/lakesare/.rvm/gems/ruby-2.2.1/bin:
/usr/local/sbin:
/usr/local/bin:
/usr/sbin:
/usr/bin:
/sbin:
/bin:...
is a : - divided list of absolute paths of directories with binaries, eg ls
binary. which you can call without mentioning the absolute path. like
~❯ rails
and, if it works, there is a rails binary in one of those paths. in out case, in
~❯ whereis rails
rails: /home/lakesare/.rvm/gems/ruby-2.2.1/bin/rails
Ruby
[$LOAD_PATH
global variable]
[1] irb(main)> $LOAD_PATH
=> ['/home/lakesare/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0', ...]
Rubygems overwrites Kernel.require
. Rubygems gem is included in standard library since ruby 1.9.
When you call require 'a'
, this is what happens:
File can be loaded from the existing Ruby loadpath?
yes -> it is loaded.
no -> installed gems are searched for a file (in /lib) that matches. if it's found in gem 'b', that gem is added to the loadpath (activated).
Rails
[autoload_paths()
rails method]
is used to autoload constants.
module A::B
C # Module.nesting => [A::B]
end
when Ruby sees constant C
, to resolve it, it looks in:
Each entry in
Module.nesting
Each entry in
Module.nesting.first.ancestors
Each entry in
Object.ancestors
ifModule.nesting.first
is nil or a module.
when Rails sees constant C
, to resolve it, Rails:
looks in every place Ruby looks at.
-
if it hasn't been found, calls
A::B.const_missing("C")
. Rails then:- Looks within autoload_paths for a/b/c.rb
-
If a matching file is found, it is loaded:
- If the correct constant is defined, it is returned
- Otherwise, an error is raised
If no matching file is found, it looks instead for
A::C
, thenC
, unless they are already definedIf none of the candidate constants can be loaded, it raises a
NameError