2

I have created a project in /Projects/test that have the following files:

/Projects/test/first.rb
/Projects/test/second.rb

In first.rb, I do:

load 'second.rb'

And it gets loaded correctly. However, if I open the console and I type $:, I don't see the current directory "." in the load path. How does Ruby know where to load that 'second.rb' from?

Hommer Smith
  • 26,772
  • 56
  • 167
  • 296

2 Answers2

1

See the documentation of Kernel#load clearly :

Loads and executes the Ruby program in the file filename. If the filename does not resolve to an absolute path, the file is searched for in the library directories listed in $:. If the optional wrap parameter is true, the loaded script will be executed under an anonymous module, protecting the calling program’s global namespace. In no circumstance will any local variables in the loaded file be propagated to the loading environment.

In case load 'second.rb' - second.rb has been internally resolved to the absolute path /Projects/test/second.rb,as your requiring file in the directory is same as required file directory. Nothing has been searched to the directories listed in$: for your case.

Just remember another way always - The load method looks first in the current directory for files

Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
  • No idea who downvoted this, so I upvoted it for you. However I'm considering why you don't say "relative" instead of "absolute". Due to the fact that the file is in the same directory as the initiated file.. Any thoughts? – Luceos Nov 13 '13 at 06:04
  • @Luceos Look at the bold line.. :) That's how they documented.. And I think it makes sense.. – Arup Rakshit Nov 13 '13 at 06:07
  • The filename that I write in load 'myfile.rb' does not actually resolve to an absolute path, but to a relative path. With require you can also load absolute path. – Hommer Smith Nov 13 '13 at 06:11
  • And why would they make load and require work differently? I am confused. – Hommer Smith Nov 13 '13 at 06:14
  • @HommerSmith Here is the answer of your [confusion](http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/) – Arup Rakshit Nov 13 '13 at 06:15
  • It does not actually say why one looks into the current directory and the other not... :) – Hommer Smith Nov 13 '13 at 06:17
  • 1
    @HommerSmith read this also - [Load Vs. Require](http://ruby.about.com/od/rubysbasicfeatures/ss/Load-Vs-Require.htm) – Arup Rakshit Nov 13 '13 at 06:21
1

Contrary to the currently accepted answer, the argument 'second.rb' does not resolve to an absolute path. If that were what was meant, you would also be able to require 'second.rb', since require has exactly the same wording about absolute paths.

I think what's happening here is just that the phrasing in the documentation for load is not clear at all about what the actual steps are. When it says "Loads and executes the Ruby program in the file filename," it means that literally — it treats the argument as a file name and attempts to load it as a Ruby program. If isn't an absolute path†, then Ruby goes through $LOAD_PATH and looks for it in those places. If that doesn't turn anything up, then it just goes ahead and tries to open it just as you passed it in. That's the logic that MRI actually follows.

† The actual check that Ruby does is essentially "Does the path start with '/', '~' or './'?".

Chuck
  • 234,037
  • 30
  • 302
  • 389
  • From the doc [Load Vs. Require](http://ruby.about.com/od/rubysbasicfeatures/ss/Load-Vs-Require.htm) I found - *The load method also looks in the current directory for files. In Ruby 1.9.x (things were different in 1.8.x),* – Arup Rakshit Nov 13 '13 at 08:58
  • *the 'require' method will not look in the current directory for files to load. In fact, one (very small but still annoying hurdle) when upgrading to 1.9.x was this exact problem, which is solved by adding the current directory to the $LOAD_PATH global variable. If there is a file called module.rb in the current directory, require 'module' or even require 'module.rb' will not work, however require './test.rb' will. Or, slightly simpler, load 'test.rb'.*.. It seems to me I was right... :) – Arup Rakshit Nov 13 '13 at 08:58
  • @ArupRakshit: I don't know what these quotes from About.com are meant to prove. Your answer was that "`second.rb` has been internally resolved to the absolute path `/Projects/test/second.rb`,as your requiring file in the directory is same as required file directory. Nothing has been searched to the directories listed here `$:`." That is not right. If it isn't an absolute path (like this case), it goes through $LOAD_PATH and tries those directories, then it just tries to go ahead and open the path as written. If you rename your file 'pathname.rb', you'll see the library takes precedence. – Chuck Nov 13 '13 at 16:34