Ruby require 的问题

dreamrise · 2012年04月04日 · 最后由 sawater 回复于 2012年10月08日 · 12446 次阅读

使用 require 'myrubyfile' 引用一个同路径下的文件无效。 d:/ruby/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `req uire': cannot load such file -- myrubyfile (LoadError)

如果改成 require './myrubyfile' 则可以。 这是神马情况?

在 WIN7 下,ruby 1.9.3 环境。

Where Ruby Finds Its Modules You use require or load to bring a library module into your Ruby program. Some of these modules are supplied with Ruby, some you installed off the Ruby Application Archive, and some you wrote yourself. How does Ruby find them?

When Ruby is built for your particular machine, it predefines a set of standard directories to hold library stuff. Where these are depends on the machine in question. You can determine this from the command line with something like:

% ruby -e 'puts $:' On a typical Linux box, you'll probably find something such as:

/usr/local/lib/ruby/site_ruby/1.6/i686-linux /usr/local/lib/ruby/site_ruby/1.6 /usr/local/lib/ruby/site_ruby /usr/local/lib/ruby/1.6/i686-linux /usr/local/lib/ruby/1.6 . The site_ruby directories are intended to hold modules and extensions that you've added. The architecture-dependent directories (i686-linux in this case) hold executables and other things specific to this particular machine. All these directories are automatically included in Ruby's search for modules.

Sometimes this isn't enough. Perhaps you're working on a large project written in Ruby, and you and your colleagues have built a substantial library of Ruby code. You want everyone on the team to have access to all of this code. You have a couple of options to accomplish this. If your program runs at a safe level of zero (see “Locking Ruby in the Safe”), you can set the environment variable RUBYLIB to a list of one or more directories to be searched. (The separator between entries depends on your platform. For Windows, it's a semicolon; for Unix, a colon.) If your program is not setuid, you can use the command-line parameter -I to do the same thing.

Finally, the Ruby variable $: is an array of places to search for loaded files. This variable is initialized to the list of standard directories, plus any additional ones you specified using RUBYLIB and -I. You can always add additional directories to this array from within your running program.

D:\work\designpatterns\chap03>ruby -e 'puts $:'
d:/ruby/Ruby1.9.3/lib/ruby/site_ruby/1.9.1
d:/ruby/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/i386-msvcrt
d:/ruby/Ruby1.9.3/lib/ruby/site_ruby
d:/ruby/Ruby1.9.3/lib/ruby/vendor_ruby/1.9.1
d:/ruby/Ruby1.9.3/lib/ruby/vendor_ruby/1.9.1/i386-msvcrt
d:/ruby/Ruby1.9.3/lib/ruby/vendor_ruby
d:/ruby/Ruby1.9.3/lib/ruby/1.9.1
d:/ruby/Ruby1.9.3/lib/ruby/1.9.1/i386-mingw32

在我的 WINDOWS 环境上需要改成 ruby -I .\ 才能运行。

ruby1.9 之前是可以的,ruby1.9 之后,好像是因为安全问题吧,具体不太清楚, 另 require_relative 也是可用的。

#4 楼 @xzgyb +1 是安全的原因。

#4 楼 @xzgyb 我擦~ 这个 id...... 老达摩阿~ 是你吧。我说看着眼熟。

@skandhas : 呵呵,!!! ~_~ !!!

和 dll 一样? 担心 hiijack?

我一般都用这个,和 1.9 的 require_relative 一个效果

require File.expand_path("./xxx", __FILE__)

前面的都说了,我来做个补充,用 load 也可以加载当前目录的文件。

load 和 require 不是一回事。 关键是 1.9 后可能在默认加载路径中,把当前目录给去掉了。 所以, 如果 myfile.rb 中 require 了一个当前目录下的 file2.rb 时,直接运行 ruby myfile.rb 会报错找不到 file2. 需要加一个-I ./的参数,把当前路径给包含进来。运行 ruby -I ./ myfile.rb 就 OK 了。

#9 楼 @hooopo 貌似 require './xxx' 就行了啊 , 写成了你那样,有什么不同么? 求指教 ! 谢谢

#12 楼 @dfang ruby1.9 把当前路径从 $LOAD_PATH 移除了。因为像你这样写会随着当前路径的变化加载不同的文件。

#13 楼 @hooopo 虎跑的这个答案的写法可疑:

应该使用 require File.expand_path("../xxx", FILE),注意有 2 个而非一个点。

@hooopo 不太懂,始终加载的是同目录下的文件啊 相对的 能举个反例吗?

#15 楼 @dfang 你切换到其他目录再执行

@hooopo @xzgyb 嗯 谢谢 不偷懒 我查了下 1.9.2 中因为安全的原因从 $LOAD_PATH 移除了. , 这里用 require_relative 也行,但是 require File.expandpath("../xxx", _FILE) 这种写法可以向前兼容的 这里分享下两个链接:http://stackoverflow.com/questions/2900370/why-does-ruby-1-9-2-remove-from-load-path-and-whats-the-alternative , http://www.faqs.org/faqs/unix-faq/faq/part2/section-13.html

#14 楼 @googya 是两个点。。 好吧 其实 Rails 就是用的这种写法

啊,被挖坟了

意思就是同一目录下

require './config.rb'

等于

require_relative 'config.rb'

是么。

又被挖坟了~

今天刚好碰见这个问题,学习下~~ #20 楼 @metal 不是啊 require './config.rb' 切换目录执行的话就找不到了

require_relative 'config.rb' 这个可以切换目录执行

我的环境:ubuntu + ruby1.93

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册