【问题标题】:Ruby 'require' error: cannot load such fileRuby 'require' 错误:无法加载此类文件
【发布时间】:2012-04-02 18:48:39
【问题描述】:

我有一个文件 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


【解决方案1】:

我刚刚尝试过,它适用于 require "./tokenizer"。希望这会有所帮助。

【讨论】:

  • 这假定 CWD 是存储脚本的目录。
  • ...这就是为什么我认为最好使用require_relative,就像我在回答中所做的那样。
  • 仍然不适合我。即使使用 require_relative。它在捆绑列表中可用
【解决方案2】:

这样做:

require_relative 'tokenizer'

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

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

其他答案声称您应该使用require './tokenizer',但这是错误答案,因为只有在tokenizer.rb 所在的同一目录中运行Ruby 进程时它才会起作用。考虑像这样使用require 的唯一原因是如果您需要支持没有require_relative 的Ruby 1.8。

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

使用require 访问加载路径上的文件是一件好事,Ruby gem 一直都在这样做。但是你不应该以. 开始对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 中的假设随着时间的推移更有可能成立。

【讨论】:

  • 请问这是什么意思?它在幕后做了什么?谢谢。
  • 知道的不多。这是 require_relative 的 documentationsource code
【解决方案3】:

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

require_relative 'tokenizer'

没有必要给它加上.rb 后缀,因为Ruby 足够聪明,无论如何都知道这就是你的意思。

【讨论】:

  • 我知道这将是一些愚蠢的事情,感谢您的帮助
  • 这假定 CWD 是存储脚本的目录。
  • @RyanBigg - 我是 ruby​​ 新手。你能解释一下这是什么意思 - Ruby 1.9 has removed the current directory from the load path 吗?当前目录和加载路径是什么?谢谢。
  • 我应该在 OP 中阅读什么内容?仅仅因为 OP 恰好有 CWD 等于带有脚本的目录并不意味着它总是这样,所以我喜欢推动一个更强大的解决方案,比如使用 require_relative。明天他可能会输入cd ..,然后输入ruby folder/main.rb,很遗憾您的解决方案不再有效。我不认为在这里使用require 有任何好处。
  • require_relative 更新(发帖时不存在,或者我不知道)
【解决方案4】:

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

【讨论】:

    【解决方案5】:

    我会推荐,

    load './tokenizer.rb'
    

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

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

    require_relative 'tokenizer'
    

    我希望这会有所帮助。

    【讨论】:

      【解决方案6】:

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

      $:.unshift('.')
      

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

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

       require './tokenizer' 
      

      然后可以继续使用

      require 'tokenizer'
      

      【讨论】:

        【解决方案7】:

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

        require_relative 'tokenizer/main'
        

        【讨论】:

          【解决方案8】:

          在搜索路径中包含当前目录怎么样?

          ruby -I. main.rb
          

          【讨论】:

            【解决方案9】:

            我使用 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' 
            

            效果很好。

            【讨论】:

              【解决方案10】:

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

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

              【讨论】:

                【解决方案11】:

                问题是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
                

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

                【讨论】:

                • 这是一个选择问题。我个人总是喜欢在交互式控制台中测试我在做什么。我犯了很多错误,我喜欢获得互动反馈。
                【解决方案12】:

                第一:

                $ sudo gem install colored2
                

                而且,你应该输入你的密码

                然后:

                $ sudo gem update --system  
                

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

                然后:

                $  rvm -v
                $ rvm get head
                

                最后 你想用什么语言?? [斯威夫特/ObjC]

                ObjC

                您想在您的库中包含一个演示应用程序吗? [是/否]

                是的

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

                您想进行基于视图的测试吗? [是/否]

                没有

                你的类前缀是什么?

                XMG

                在您的新库上运行 pod install。

                【讨论】:

                  【解决方案13】:

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

                  【讨论】:

                  • 为清楚起见,我认为您应该在此处给出重复的部分代码并进行修复。否决票不是我的
                  猜你喜欢
                  • 2013-09-30
                  • 2015-12-16
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-03-16
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多