【问题标题】:Ruby: 'require' returns false even though file not loadedRuby:即使文件未加载,“require”也会返回 false
【发布时间】:2017-05-26 23:36:54
【问题描述】:

我有这个代码:

puts require './item'
puts $"

class Light < Item
  #code
end

Itemitem.rb 中的类:

require './v3d'
require './ray'

class Item
  attr_accessor :pos 

  def initialize(pos)
    @pos = pos
  end

  def check(pos, dir)
    return nil
  end

  def normal(ray)
    return nil
  end
end

当我运行我的程序时会打印这个输出:

false
enumerator.so
thread.rb
rational.so
complex.so
/usr/lib/x86_64-linux-gnu/ruby/2.3.0/enc/encdb.so
/usr/lib/x86_64-linux-gnu/ruby/2.3.0/enc/trans/transdb.so
/usr/lib/ruby/2.3.0/unicode_normalize.rb
/usr/lib/x86_64-linux-gnu/ruby/2.3.0/rbconfig.rb
/usr/lib/ruby/2.3.0/rubygems/compatibility.rb
/usr/lib/ruby/2.3.0/rubygems/defaults.rb
/usr/lib/ruby/2.3.0/rubygems/deprecate.rb
/usr/lib/ruby/2.3.0/rubygems/errors.rb
/usr/lib/ruby/2.3.0/rubygems/version.rb
/usr/lib/ruby/2.3.0/rubygems/requirement.rb
/usr/lib/ruby/2.3.0/rubygems/platform.rb
/usr/lib/ruby/2.3.0/rubygems/basic_specification.rb
/usr/lib/ruby/2.3.0/rubygems/stub_specification.rb
/usr/lib/ruby/2.3.0/rubygems/util/list.rb
/usr/lib/x86_64-linux-gnu/ruby/2.3.0/stringio.so
/usr/lib/ruby/2.3.0/rubygems/specification.rb
/usr/lib/ruby/2.3.0/rubygems/exceptions.rb
/usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb
/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_gem.rb
/usr/lib/ruby/2.3.0/monitor.rb
/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb
/usr/lib/ruby/2.3.0/rubygems.rb
/usr/lib/ruby/vendor_ruby/did_you_mean/version.rb
/usr/lib/ruby/vendor_ruby/did_you_mean/core_ext/name_error.rb
/usr/lib/ruby/vendor_ruby/did_you_mean/levenshtein.rb
/usr/lib/ruby/vendor_ruby/did_you_mean/jaro_winkler.rb
/usr/lib/ruby/vendor_ruby/did_you_mean/spell_checkable.rb
/usr/lib/ruby/2.3.0/delegate.rb
/usr/lib/ruby/vendor_ruby/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb
/usr/lib/ruby/vendor_ruby/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb
/usr/lib/ruby/vendor_ruby/did_you_mean/spell_checkers/name_error_checkers.rb
/usr/lib/ruby/vendor_ruby/did_you_mean/spell_checkers/method_name_checker.rb
/usr/lib/ruby/vendor_ruby/did_you_mean/spell_checkers/null_checker.rb
/usr/lib/ruby/vendor_ruby/did_you_mean/formatter.rb
/usr/lib/ruby/vendor_ruby/did_you_mean.rb
/home/<user>/Documents/ruby/ray/write_ppm.rb
/home/<user>/Documents/ruby/ray/v3d.rb
/home/<user>/Documents/ruby/ray/pixel.rb
/home/<user>/Documents/ruby/ray/image.rb
/home/<user>/Documents/ruby/ray/material.rb

然后抛出:

/home/<user>/Documents/ruby/ray/light.rb:4:in `<top (required)>': uninitialized constant Item (NameError)

require './item' 被调用时,没有错误并且它返回false。根据我对require 工作原理的理解,程序似乎错误地认为它不需要加载item.rb。为什么会发生这种情况,我该如何解决?

编辑:扩展了一些代码

【问题讨论】:

  • 你能告诉我们你的 item.rb 是什么样的吗?感觉你的类的定义可能有问题。
  • item.rb 只包含 Item 类的创建。它的唯一目的是拥有子类,因此几乎没有代码。我认为相关的是 require './item' 返回 false 没有错误,但从 puts $" 可以清楚地看出 item.rb 从未加载过。

标签: ruby require


【解决方案1】:

作为一个通用答案,与 op 无关,而是因为我遇到了类似的问题,并被搜索引擎指出。

基本上require 'http' 在 gem 未加载时返回 false。

我发现加载路径中有一个http.rb 文件,并且正在加载它而不是标准 gem。因此,请仔细检查库加载路径和 gem 名称下的 ruby​​ 文件的文件名是否冲突。

【讨论】:

    【解决方案2】:

    我通过为每个文件完全重写我的require 语句解决了这个问题。我认为问题是这样的:

    • item.rb 包含require './ray'
    • ray.rb 包含require './light'
    • light.rb 包含 require './item'class Light &lt; Item

    在加载item.rb 时,解释器发现它还需要加载ray.rb,因此需要加载light.rb。当它到达light.rb 内的require './item' 时,它返回false,因为它正在加载该文件。但是,由于它还没有完成加载,它没有出现在$" 中。然后解释器需要访问Item 类的定义来完成加载light.rb,但是因为它需要完成加载light.rb 来加载item.rb,解释器需要NameError

    【讨论】:

      【解决方案3】:

      你说得对,如果require 'my_lib' 返回false,那么'my_lib' 已经被加载。然而,这与定义MyLib 类不同。您的 item.rb 是否定义了 Item 类?

      此外,Item 也可能在命名空间层次结构中的其他位置定义。例如如果您的 item.rb 在 some_gem/item.rb 中,并且您从 some_gem/ 调用 require,它将成功加载,但类的名称可能是 SomeGem::Item。在这种情况下,您将无法直接从根命名空间访问它。

      我能想到的最后一件事是 item.rb 文件正在更改,或者有一些非常动态的部分使解释器感到困惑。

      我认为问题是其中之一,然后才认为 require 在某种程度上搞砸了。

      【讨论】:

      • 是的,Item 类是在item.rb 文件中定义的,其中的代码很少。 puts $" 调用的结果显示 item.rb 未加载,即使(之前的)require './item' 调用返回 false 且没有错误。
      • 很奇怪...它肯定能找到文件,否则会引发LoadError。 require$" 通常都有非常一致的行为,所以我猜要么a)我们在某个地方忽略了一些愚蠢的东西,要么b)正在进行一些疯狂的元编程。你能给我们更多的信息吗?比如说 item.rb 的内容和 puts $" 的完整输出?如果没有更多信息,我们只能猜测。
      • 我添加了item.rb$"的所有输出
      【解决方案4】:

      【讨论】:

      • 我试过用require_relative,效果一样。我最困惑的是require './item'require_relative 'item'都返回false没有错误,但是从puts $",很明显item.rb没有被加载。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多