74

require什么require_dependency不同?
如何require_dependency在开发中自动重新加载类但require不能?

我深入研究了 RailsActiveSupport::Dependencies和 dispatcher.rb 代码。我在require_dependency's 的代码中看到的是它基本上将常量添加到autoloaded_constants数组中。但它会clear_application在每次请求后在内部调度程序中清除。

有人可以给出明确的解释或向我指出一些有帮助的资源吗?

4

2 回答 2

134

require(及其表亲load)是核心 Ruby 方法。require_dependency是一种帮助 Rails 处理依赖管理问题的方法。长话短说,它允许 Rails 在开发模式下重新加载类,这样您就不必在每次更改代码时都重新启动服务器。Rails 框架将require_dependency您的代码,以便它可以跟踪并在进行更改时重新加载它。标准的 Rubyrequire不这样做。作为应用程序(或插件/引擎)开发人员,您不必担心,require_dependency因为这纯粹是 Rails 内部的。

Rails 类加载过程的神奇之处在于 ActiveSupport::Dependencies 模块。此代码扩展了默认的 Ruby 行为,以允许 Rails 应用程序中的代码使用 Rails 的路径和文件命名约定自动加载模块(包括从 Module 继承的类)。这消除了程序员require像在普通 Ruby 应用程序中那样在调用中乱扔代码的需要。

换句话说,这让您可以class Admin::User在文件中定义,并且当您从应用程序的另一部分(如控制器)app/models/admin/user.rb调用时,Rails 会知道您在说什么。Admin::User.new如果不涉及 ActiveSupport::Dependencies,您将不得不手动完成require所需的一切。

如果您来自 C#、Java 等静态类型语言,那么这可能会令人惊讶:Rails 代码在需要时才会加载。例如,User模型类没有定义,user.rb也没有加载,直到您尝试调用User.whatever_method_here. Rails 阻止 Ruby 抱怨缺少的常量,加载 的代码User,然后允许 Ruby 正常运行。

虽然我不能说出您的具体需求,但如果您确实需要require_dependency在插件或引擎中使用该方法,我会感到非常惊讶。如果您遵循 Rails 约定,您也不应该手动调整 $LOAD_PATH。这不是“Rails 方式”。

在 Ruby 和 Rails 的世界中,简单和清晰是关键。如果您只想编写一个插件或引擎,并且您已经深入研究了内部结构,那么您可以考虑从不同的角度解决您的问题。我的直觉告诉我,您可能正在尝试做一些不必要的复杂事情。但是话又说回来,我不知道你在做什么!:)

于 2011-03-07T00:52:43.010 回答
26

require_dependency当您想要重新打开未在引擎中定义的类(例如在另一个引擎或 Rails 应用程序中)并重新加载它时,它在引擎中很有用。在这种情况下,这样的工作:

# app/controllers/my_engine/documents_controller.rb
require_dependency MyEngine::Engine.root.join('app', 'controllers', 'my_engine', 'documents_controller').to_s

module MyEngine
  class DocumentsController
    def show
      render :text => 'different'
    end
  end
end
于 2013-11-14T10:19:19.560 回答