Ruby-on-rails 什么时候在 Rails 中调用“require”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3587667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When to call a "require" in Rails?
提问by Cimm
I have a more conceptual question in Rails... or Ruby for that matter:
我在 Rails 或 Ruby 中有一个更概念性的问题:
Is it best to call a require right before the method that needs it, group my requires at the beginning of the class or somewhere in an initializer when Rails boots?
是否最好在需要它的方法之前调用 require ,在类的开头或 Rails 启动时的初始化程序中的某个地方将我的需求分组?
Does it matter from a performance point of view? From a readability point of view? Does it make a difference if I'm using Rails 3?
从性能的角度来看,这很重要吗?从可读性的角度?如果我使用 Rails 3 会有什么不同吗?
Thanks!
谢谢!
采纳答案by tadman
If you're concerned about performance then you should require things in the context of where they are needed so that if that portion of your code is not exercised, the library is not loaded. Any subsequent calls to requirehave no effect as that file has already been loaded. This ends up looking like something along the lines of:
如果您担心性能,那么您应该在需要它们的上下文中要求某些东西,以便如果不执行该部分代码,则不会加载该库。任何后续调用require都无效,因为该文件已经加载。这最终看起来像以下内容:
if (user.using_openid?)
require 'openid'
# ... Do OpenID stuff
end
While this is more efficient in terms of resources, it can make it very difficult to determine the dependencies of your application. Declaring these up-front makes it clear to other people maintaining the software. Keep in mind that "other people" always includes your future self when you've forgotten about some details of your application.
虽然这在资源方面更有效,但它可能会使确定应用程序的依赖项变得非常困难。预先声明这些可以让其他维护软件的人一目了然。请记住,当您忘记了申请的某些细节时,“其他人”总是包括您未来的自己。
You're technically allowed to require anything at any time, late or early, but declaring your requirements up front is better from a design perspective. If you find that there is an element that is used only intermittently and takes an unusual amount of time or memory to load, then you should probably document that up front in your requirements file. For example:
从技术上讲,您可以在任何时间(晚或早)提出任何要求,但从设计的角度来看,提前声明您的要求会更好。如果您发现某个元素仅间歇性地使用,并且加载需要的时间或内存不寻常,那么您可能应该将其预先记录在您的需求文件中。例如:
require 'library1'
require 'library2'
require 'library3'
require 'library4'
require 'library5'
# Other libraries loaded as required:
# * slowimagelibrary
# * slowencryptionlibrary
# * openid
Arguably this is less of an issue with bundlerbecause you can have your gems declared up front more formally and the actual requirecall can come later.
可以说这对于bundler来说不是问题,因为您可以更正式地预先声明您的 gem,而实际require调用可以稍后进行。
回答by eregon
If you consider vanilla Ruby, 'require' is mostly used in the first lines, because you then are sure you have access to what you need, and it is easier to find and read what dependency you need.
如果您考虑使用 vanilla Ruby,“require”主要用于第一行,因为这样您就可以确定可以访问所需的内容,并且更容易找到和阅读所需的依赖项。
There are a few cases when you want to load a gem only in a method, because this is not really needed for your script to work (e.g.: a optional visualization).
在某些情况下,您只想在方法中加载 gem,因为这并不是您的脚本工作所真正需要的(例如:可选的可视化)。
With Rails, I believe it depends on what you want to do.
对于 Rails,我相信这取决于您想要做什么。
If you use Bundler, you can assume your gem has been 'required' (you can of course override what is required with the :require option).
如果您使用 Bundler,您可以假设您的 gem 是“必需的”(您当然可以使用 :require 选项覆盖所需的内容)。
If it is some stuff you want to autoload when the server start (like validators or form builders), then you should look how to do with the config (autoload_paths and eager_load_paths).
如果你想在服务器启动时自动加载一些东西(比如验证器或表单构建器),那么你应该看看如何处理配置(autoload_paths 和eager_load_paths)。
require can also be used to load only a part of a gem, like an extension to it. Then it is of course required where the configuration is.
require 也可用于仅加载 gem 的一部分,例如它的扩展。那么配置在哪里当然是需要的。
You might be concerned if you work in a multi-threaded environment, as they are some problems with that. You must then ensure everything is loaded before having your threads running. (Something like the class constant is loaded, but the methods not yet, there was a good article but I can not find it anymore).
如果您在多线程环境中工作,您可能会担心,因为它们存在一些问题。然后,您必须确保在运行线程之前加载所有内容。(类常量已加载,但方法尚未加载,有一篇不错的文章,但我再也找不到了)。
You might also want to try {Module,Kernel}.autoload, Rails extensively use it to load only what is necessary when accessed (but it looks rather ugly).
您可能还想尝试 {Module,Kernel}.autoload,Rails 广泛使用它来仅加载访问时需要的内容(但它看起来很丑陋)。
You can also hack it yourself with const_missing (so this can do plain lazy-loading, if you accept a structure). This is a simple example (will not be appropriate for nested classes).
你也可以用 const_missing 自己破解它(如果你接受一个结构,这可以做简单的延迟加载)。这是一个简单的示例(不适用于嵌套类)。
def Object.const_missing c
if (file = Dir["#{c.downcase}.rb"]).size == 1
require_relative(file)
end
if const_defined? c
const_get c
else
super # Object < Module
end
end
About performance, a call to require is relatively expensive, so if you know you are going to use it, do it only once if possible. However, to manage complex dependencies within your project, you might need to require relative files. Then require_relativeis the way to go in 1.9.
关于性能,调用 require 的成本相对较高,因此如果您知道要使用它,请尽可能只调用一次。但是,要管理项目中的复杂依赖项,您可能需要相关文件。然后require_relative是 1.9 的方法。
Lastly, for a project, I would recommend to require all in the main file in lib/, with some Dir["**/*.rb"]expression. You would then rarely need to require_relative, because it is only needed if you reference in the body of the class another constant (all the contents of the methods are not resolved, so there is no problem with that).
最后,对于一个项目,我建议在 lib/ 的主文件中要求所有内容,并带有一些Dir["**/*.rb"]表达式。然后require_relative,您很少需要,因为只有在类的主体中引用另一个常量时才需要它(方法的所有内容都没有解析,因此没有问题)。
Another solution would be to define these constants in your main file, it would also give you an idea of the structure.
另一种解决方案是在主文件中定义这些常量,它还可以让您了解结构。

