Ruby'require'错误:无法加载此类文件

问题描述 投票:160回答:13

我有一个文件,main.rb,内容如下:

require "tokenizer.rb"

tokenizer.rb文件位于同一目录中,其内容为:

class Tokenizer
    def self.tokenize(string)
        return string.split(" ")
    end
end

如果我尝试运行main.rb,我收到以下错误:

C:\Documents and Settings\my\src\folder>ruby main.rb

C:/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- tokenizer.rb (LoadError)
        from C:/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require '
        from main.rb:1:in `<main>'

我只是注意到,如果我使用load而不是require一切正常。这可能是什么问题?

ruby require
13个回答
180
投票

我刚试过,它适用于require "./tokenizer"。希望这可以帮助。


0
投票

第一:

$ sudo gem install colored2

而且,您应该输入密码

然后 :

$ sudo gem update --system  

出现更新rubygems-update错误:执行gem时...(OpenSSL :: SSL :: SSLError)主机名“gems.ruby-china.org”与服务器证书不匹配

然后:

$  rvm -v
$ rvm get head

最后你想用什么语言? [Swift / ObjC]

ObjC

您想在图书馆中加入演示应用程序吗? [是/否]

您将使用哪些测试框架? [Specta / Kiwi /无]

没有

你想做基于视图的测试吗? [是/否]

没有

你的班级前缀是什么?

XMG

在新库上运行pod安装。


0
投票

对于那些绝对确定他们的相对路径是正确的人,我的问题是我的文件没有.rb扩展名! (尽管我使用RubyMine创建文件并选择在创建时使用Ruby文件。)

仔细检查文件中的文件扩展名!


0
投票

如何在搜索路径中包含当前目录?

ruby -I. main.rb

-1
投票

你需要给出路径。至少你应该从当前目录中提供路径。它肯定会起作用。 。/文件名


166
投票

这样做:

require_relative 'tokenizer'

如果你把它放在与tokenizer.rb在同一目录下的Ruby文件中,无论你当前的工作目录(CWD)是什么,它都能正常工作。

解释为什么这是最好的方法

其他答案声称你应该使用require './tokenizer',但这是错误的答案,因为只有你在tokenizer.rb所在的同一目录中运行你的Ruby进程才会有效。几乎是考虑使用require的唯一理由就是如果你需要支持Ruby 1.8,它没有require_relative

require './tokenizer'的答案今天可能适合你,但它不必要地限制了你运行Ruby代码的方式。明天,如果您想将文件移动到不同的目录,或者只是想从不同的目录启动Ruby进程,您将不得不重新考虑所有这些require语句。

使用require访问加载路径上的文件是件好事,Ruby宝石一直在这样做。但你不应该用require开始.的论证,除非你做了一些非常特别的事情并知道你在做什么。

当您编写对其环境做出假设的代码时,您应该仔细考虑要做出的假设。在这种情况下,最多有三种不同的方法来要求tokenizer文件,每种方法都有不同的假设:

  1. require_relative 'path/to/tokenizer':假设两个Ruby源文件之间的相对路径保持不变。
  2. require 'path/to/tokenizer':假设path/to/tokenizer位于加载路径上的一个目录($LOAD_PATH)中。这通常需要额外的设置,因为您必须在加载路径中添加一些内容。
  3. require './path/to/tokenizer':假设从Ruby进程的当前工作目录到tokenizer.rb的相对路径将保持不变。

我认为,对于大多数人和大多数情况,选项#1和#2中的假设更可能随着时间推移而成立。


86
投票

Ruby 1.9已经从加载路径中删除了当前目录,因此您需要对此文件执行相对要求,正如David Grayson所说:

require_relative 'tokenizer'

没有必要用.rb对它进行后缀,因为Ruby非常聪明,无论如何都知道你的意思。


37
投票

require$LOAD_PATH加载文件。如果您想要相对于当前正在执行的文件而不是$LOAD_PATH的文件,请使用require_relative


14
投票

我会建议,

load './tokenizer.rb'

鉴于,您知道该文件位于同一工作目录中。

如果您尝试相对于文件要求它,您可以使用

require_relative 'tokenizer'

我希望这有帮助。


11
投票

另一个不错的小方法是在您的加载路径中包含当前目录

$:.unshift('.')

您可以将其推送到$ :( $ LOAD_PATH)数组,但unshift将强制它在加载路径的其余部分之前加载当前工作目录。

在加载路径中添加当前目录后,无需继续指定

 require './tokenizer' 

并且可以回去使用

require 'tokenizer'

2
投票

如果它位于gem lib目录中,这将很好地工作,这是tokenizer.rb

require_relative 'tokenizer/main'

1
投票

我使用jruby-1.7.4编译我的ruby代码。

require 'roman-numerals.rb' 

是抛出以下错误的代码。

LoadError: no such file to load -- roman-numerals
  require at org/jruby/RubyKernel.java:1054
  require at /Users/amanoharan/.rvm/rubies/jruby-1.7.4/lib/ruby/shared/rubygems/custom_require.rb:36
   (root) at /Users/amanoharan/Documents/Aptana Studio 3 Workspace/RubyApplication/RubyApplication1/Ruby2.rb:2

我从require中删除了rb并给了

require 'roman-numerals' 

它工作正常。


0
投票

问题是require不从当前目录加载。这也是我的想法,但后来我发现了这个thread。例如,我尝试了以下代码:

irb> f = File.new('blabla.rb')
=> #<File:blabla.rb>
irb> f.read
=> "class Tokenizer\n    def self.tokenize(string)\n        return string.split(
\" \")\n    end\nend\n"
irb> require f
LoadError: cannot load such file -- blabla.rb
        from D:/dev/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `req
uire'
        from D:/dev/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `req
uire'
        from (irb):24
        from D:/dev/Ruby193/bin/irb:12:in `<main>'

可以看出它读取文件确定,但我不能要求它(路径未被识别)。这里的代码有效:

irb f = File.new('D://blabla.rb')
=> #<File:D://blabla.rb>
irb f.read
=> "class Tokenizer\n    def self.tokenize(string)\n        return string.split(
\" \")\n    end\nend\n"
irb> require f
=> true

正如您所看到的那样,您是否指定了文件正确加载的完整路径。

© www.soinside.com 2019 - 2024. All rights reserved.