ruby - Ruby 需要全有或全无吗?

标签 ruby require

有没有require的版本在 ruby​​ 中,要么加载整个文件,要么什么也不加载?

问题是 require 从顶部开始加载,如果它遇到问题,最终会得到未完成的定义,例如,以下内容仍然会加载 class A即使module C未定义:

class B
  include C
end

在我的特定情况下,我有大量相互依赖的文件,以及加载这些文件的加载器。为了举例说明,我将把文件集简单地分为 4 个文件(a.rb、b.rb、c.rb 和 w.rb)。以下是这些文件的列表:

# In file a.rb
class A
  @foo = []
  @foo.push("in A")

  def self.inherited(subclass)
    foo = @foo.dup
    subclass.instance_eval do
      @foo = foo
    end
  end

  def self.get_foo
    @foo
  end
end

# In file b.rb
class B < A
  include C # if C is not already defined, the following line will not get executed although B will be defined.
  @foo.push("in B")
end

# In file c.rb
module C
end

# In file w.rb
class W < B
  @foo.push("in W")
end

加载器的工作方式是获取当前文件的列表,并尝试逐一要求它们。如果任何文件失败,它将保留在列表中并稍后重试。代码是这样的:(为了简单起见,删除了很多细节)

# In file loader.rb
files = Dir["*.rb"].reject { |f| f =~ /loader/ }
files.sort! # just for the purpose of the example, to make them load in an order that causes the problem
files.reject! { |f| require(f) rescue nil } while files.size > 0

我最终希望它加载A,然后发现B不能单独加载(所以跳过它),然后加载C,然后发现W还不能加载(所以跳过它),然后返回先B,然后W。

在这种情况下,输出 p W.get_foo将是["in A", "in B", "in W"] ,这就是我想要的。

实际发生的情况是,它加载A,然后部分加载B,然后C,然后当谈到W时,它相信它可以加载它(因为B已经定义了)。这会触发self.inherited在错误的时间编写代码,并复制尚未就绪的值 @foo ,给出输出 p W.get_foo错误地为 ["in A", "in W"] .

要么全有,要么全无 require就可以解决了。

有什么想法吗?

最佳答案

如果一个文件依赖于另一个文件,则该文件本身应该需要依赖关系。例如,b.rb 应如下所示:

require 'a'
require 'c'

class B < A
  include C # if C is not already defined, the following line will not get executed although B will be defined.
  @foo.push("in B")
end

w.rb应如下所示:

require 'b'

class W < B
  @foo.push("in W")
end

此后,外部加载顺序不再重要,也不需要“全有或全无”的方法。当 b 加载时,它首先会看到 a 的 require 并意识到它已经被加载,然后它会 require c 因为它意识到了它尚未加载。当再次需要c时,它将从外循环中跳过。

注意:请小心您的 $LOAD_PATH 和传递给 require 的路径。当路径相同时,Ruby 仅识别重复的需求。最好使用相对路径(相对于$LOAD_PATH中的路径)而不是绝对路径;否则,一个文件可能会被加载两次。

关于ruby - Ruby 需要全有或全无吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1113532/

相关文章:

ruby-on-rails - Nginx - passanger 显示 404 not found for rails controllers

php - 将 PHP 文件包含到 HTML 文件中

javascript - RequireJS, $.Deferred 怎么办?

javascript - 制作一个小型 HTML 应用程序来更新 JSON 文件

javascript - Node : Is calling functions from require's cache as fast as functions in global scope?

php - php中 "include"和 "require"的区别

ruby-on-rails - Ruby Gem 随机返回编码错误

ruby - 在 Ruby 中测试整个脚本

ruby - 我可以使用 RVM 为所有用户维护单一版本的 Ruby 吗?

ruby-on-rails - rails 上的 ruby 。付费发表文章