自动加载东西的魔力
我认为控制完成自动加载内容的文件夹的选项已在其他答案中充分涵盖。但是,如果其他人虽然根据需要修改了自动加载路径,但在加载东西时遇到了问题,那么这个答案试图解释这个自动加载背后的魔力是什么。
因此,当涉及从子目录加载内容时,您应该注意一个问题或约定。有时 Ruby/Rails 的魔力(这次主要是 Rails)会让人很难理解为什么会发生某些事情。只有当模块名称对应于父目录名称时,才会加载自动加载路径中声明的任何模块。因此,如果您尝试输入以下内容lib/my_stuff/bar.rb
:
module Foo
class Bar
end
end
它不会自动加载。然后再一次,如果您将父目录重命名为foo
因此将您的模块托管在 path: lib/foo/bar.rb
。它会在那里为你服务。另一种选择是通过模块名称命名要自动加载的文件。显然,那个名称只能有一个文件。如果您需要将您的东西拆分成多个文件,您当然可以使用该文件来要求其他文件,但我不建议这样做,因为在开发模式下并且您修改这些其他文件时,Rails 无法自动执行为您重新加载它们。但是,如果您真的想要,您可以拥有一个模块名称的文件,然后指定使用该模块所需的实际文件。所以你可以有两个文件:lib/my_stuff/bar.rb
并且lib/my_stuff/foo.rb
前者与上面相同,后者包含一行:require "bar"
这将是一样的。
PS我觉得有必要补充一件更重要的事情。最近,每当我想在 lib 目录中有一些需要自动加载的东西时,我倾向于开始思考,如果这是我实际上专门为这个项目开发的东西(通常是这样,可能有一天变成许多项目或 git 子模块等中使用的“静态”代码片段。在这种情况下,它肯定应该在 lib 文件夹中)那么它的位置可能根本不在 lib 文件夹中。或许应该在app文件夹下的子文件夹里·我有一种感觉,这是新的rails做事方式。显然,无论您在自动加载路径中放置您的东西的任何地方,同样的魔法都在发挥作用,因此这对这些东西有好处。无论如何,这只是我对这个问题的想法。你可以不同意。:)
更新:关于魔法的类型..
正如 severin 在他的评论中指出的那样,核心“自动加载模块机制”肯定是 Ruby 的一部分,但自动加载路径的东西不是。你不需要 Rails 来做autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar")
. 当您第一次尝试引用模块 Foo 时,它将为您加载。然而,Rails 所做的是它为我们提供了一种尝试从注册文件夹中自动加载内容的方法,并且它已经以需要假设一些关于命名约定的方式实现。如果它没有像那样实现,那么每次您引用当前未加载的内容时,它都必须检查所有自动加载文件夹中的所有文件,并检查其中是否包含您要引用的内容。这反过来又会破坏自动加载和自动重新加载的想法。但是,有了这些约定,它可以从模块/类中扣除您尝试加载可能定义的位置并加载它。