When you require something, Ruby looks for a matching file in all the directories in the load path. The load path is stored in the global variable $LOAD_PATH.
Consider the following directory structure:
top_level.rb underlings/ slave.rb equal.rb
You’ll get an error if you try to require "slave" from top_level.rb. When you require something, Ruby looks for a matching file in the directories of the $LOAD_PATH. The directory underlings/ is not automatically added to the $LOAD_PATH by Ruby, so the require fails.
If you on the other hand add underlings/ to the $LOAD_PATH, it will work. Adding directories to the load path is easy.
# top_level.rb
$LOAD_PATH << File.join(File.dirname(__FILE__), "underlings")
require "slave"
File.dirname(__FILE__) and File.join is used to get the full absolute path to the underlings/ directory. You should only put absolute paths such as "/usr/local/foo" (or "C:\foo\bar" on Windows) in the $LOAD_PATH, and avoid things like $LOAD_PATH << "lib/foo".
The snippet above will run successfully, because the require statement is able to handle "slave" based on what’s in the $LOAD_PATH. As you can see, $LOAD_PATH is an array, and the directory names it contains are strings.
The current directory is in the load path
If you inspect $LOAD_PATH in IRb, you’ll find "." in it. That dot reperesents the current directory, and lets you require a file that is in the same directory as the file you require from. If foo.rb and bar.rb, you can require "bar" from foo.rb without modifying the $LOAD_PATH.
That $: thing
$: is a shorthand for $LOAD_PATH. So now you know.
(In fact, $LOAD_PATH is longhand for $:. Yeah! Thanks, bryanl.)