$LOAD_PATH in Ruby
这篇文章搞定了Ubuntu上的RMagick
$LOAD_PATH /Library/Ruby/Site/1.8
# => /Library/Ruby/Site/1.8/powerpc-darwin9.0
# => /Library/Ruby/Site/1.8/universal-darwin9.0
# => /Library/Ruby/Site
# => /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8
# => /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/powerpc-darwin9.0
# => /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0
# => .
That’s the load path on my OS X system. A bunch of directories, and . (dot). The dot represents the current working directory.
Let’s investigate
# ~/foo/top_level.rb
puts "I rule the world"
require "underlings/slave"
# ~/foo/underlings/slave.rb
puts "I am a slave."
require "equal"
# ~/foo/underlings/equal.rb
puts "I am equal."
Close your eyes. You open a terminal. The current working directory is ~/foo.
$ ~/foo: ruby top_level.rb
I rule the world!
I am a slave.
./underlings/slave.rb:3:in `require': no such file to load -- equal (LoadError)from ./underlings/slave.rb:3
from top_level.rb:3:in `require'
from top_level.rb:3
Ruby looks for equal in the directories in the load path.
~/foo/underlings isn’t in the load path, which means Ruby can’t find equal.rb.
It raises a LoadError.
$ ~/foo: cd underlings
$ ~/foo/underlings: ruby slave.rb
I am a slave.
I am equal.
This time, Ruby finds equal. That’s because the curent working directory is the directory that contains equal.rb, and Ruby adds the current working directory to the load path.
Modifying the load path
Let’s add ~/foo/underlings to the load path.
# ~/foo/top_level.rb
puts "I rule the world"
$LOAD_PATH << "~/foo/underlings"
require "underlings/slave"
Back to the imaginary terminal.
$ ~/foo/underlings: cd .. $ ~/foo: ruby top_level.rb I rule the world! I am a slave. I am equal.
Modifying the load path in a sensible way
# ~/foo/top_level.rb
puts "I rule the world"
$LOAD_PATH << File.join(File.dirname(__FILE__), "underlings")
require "slave"
- File.join is a cross platform file path generator. Platforms vary between using forward and backwards slashes to delimit directories, so you want to do
File.join('foo', 'bar'), not"foo/bar", when referring to directories. - Instead of adding the relative ~/foo/underlings,
File.dirname(__FILE__)is used. It returns the absolute path to the current file. - Because ~/foo/underlings is in the load path,
require "underlings/slave"is pointless.require "slave"instead.
That $: thing
$:is a shorthand for $LOAD_PATH. So now you know.
(In fact, $LOAD_PATH is longhand for $:. Yeah! Thanks, bryanl.)
Add directories to the beginning of your load path
Speed is some times convenient. If you have a lot of requires to your own load-pathed directories, you might want to add your directory to the beginning of the load path, so that Ruby will look in your own directories before it starts traversing through the system directories.
The load path is an array, Array#unshift to the rescue.
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'foo'))
And there you go.
本文深入探讨了Ruby中$LOAD_PATH的工作原理,通过实例演示如何在Ruby程序中正确地使用require语句来加载自定义模块,并介绍了如何修改加载路径以解决找不到模块的问题。
202

被折叠的 条评论
为什么被折叠?



