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

The*_*onk 166 ruby require

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

require "tokenizer.rb"
Run Code Online (Sandbox Code Playgroud)

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

class Tokenizer
    def self.tokenize(string)
        return string.split(" ")
    end
end
Run Code Online (Sandbox Code Playgroud)

如果我尝试运行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>'
Run Code Online (Sandbox Code Playgroud)

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

Pas*_*cal 184

我只是尝试过并且可以使用require "./tokenizer".希望这可以帮助.

  • ...这就是为什么我认为使用`require_relative'比我在答案中更好. (23认同)
  • 这假定CWD是存储脚本的目录. (15认同)

Dav*_*son 178

这样做:

require_relative 'tokenizer'
Run Code Online (Sandbox Code Playgroud)

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

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

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

require './tokenizer'回答可能会为你今天的工作,但它不必要的限制,可以在其中运行Ruby代码的方式.明天,如果要将文件移动到其他目录,或者只是想从不同的目录启动Ruby进程,则必须重新考虑所有这些require语句.

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

当您编写对其环境做出假设的代码时,您应该仔细考虑要做出的假设.在这种情况下,最多有三种不同的方式来要求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中的假设更可能随着时间推移而成立.


Rya*_*igg 87

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

require_relative 'tokenizer'
Run Code Online (Sandbox Code Playgroud)

没有必要用它后缀.rb,因为Ruby足够聪明,无论如何都知道你的意思.

  • 这假定CWD是存储脚本的目录. (3认同)

Jör*_*tag 37

require从中加载文件$LOAD_PATH.如果您想要一个相对于当前正在执行的文件而不是来自的文件$LOAD_PATH,请使用require_relative.


Mat*_*rey 14

我会建议,

load './tokenizer.rb'
Run Code Online (Sandbox Code Playgroud)

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

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

require_relative 'tokenizer'
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助.


小智 11

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

$:.unshift('.')
Run Code Online (Sandbox Code Playgroud)

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

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

 require './tokenizer' 
Run Code Online (Sandbox Code Playgroud)

并且可以回去使用

require 'tokenizer'
Run Code Online (Sandbox Code Playgroud)


Dou*_*len 8

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

require_relative 'tokenizer/main'
Run Code Online (Sandbox Code Playgroud)