在Rails中,require,require_dependency和常量重载有何关系?


70

如何requirerequire_dependency不同?
如何require_dependency自动重载开发中的类却require不能自动重载?

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

有人可以给出清晰的解释或向我指出一些有用的资源吗?


仅供参考:类重载是在引擎中自动处理的(引擎本身就是带有应用程序/文件夹的插件),就像在普通应用程序中一样。
2009年

谢谢,是的,我知道这一点。但是,这又引出了另一个问题:我可以在插件中使用其他插件吗?说,我想在自己的插件中使用act_as_xxx插件,是否可以将act_as_xxx放入插件的vendor / plugins目录中,然后将路径添加到$ LOAD_PATH?我想我应该在另一个线程中问这个问题,这与我原来的问题无关。

Answers:


127

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的世界中,简单和清晰是关键。如果您要做的只是编写一个插件或引擎,而您已经深入研究内部结构,那么您可以考虑从另一个角度解决问题。我的直觉告诉我,您可能正在尝试做一些不必要的复杂工作。但是话又说回来,我不知道你到底在做什么!:)


24

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.