Ruby:'要求'即使文件未加载,也返回false

时间:2017-01-12 00:53:43

标签: ruby require

我有这段代码:

puts require './item'
puts $"

class Light < Item
  #code
end
Item中的

item.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。为什么会发生这种情况,我该如何解决?

编辑:扩展了一些代码

4 个答案:

答案 0 :(得分:1)

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

  • item.rb包含require './ray'
  • ray.rb包含require './light'
  • light.rb包含require './item'class Light < Item

加载item.rb时,解释程序看到它还需要加载ray.rb,因此light.rb。当它到达require './item' light.rb时,它返回false,因为它正在加载该文件。但是,由于它尚未完成加载,因此未显示在$"中。然后,解释器需要访问Item类的定义才能完成加载light.rb,但因为它需要加载light.rb来加载item.rb,所以解释器需要{ {1}}。

答案 1 :(得分:0)

答案 2 :(得分:0)

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

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

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

我认为这个问题就是其中之一,然后才会认为要求有些混乱。

答案 3 :(得分:0)

作为一个通用的答案,与 op 无关,而是因为我有一个类似的问题并且被搜索引擎指出在这里。

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

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