магия автозагрузки
Я думаю, что опция, управляющая папками, из которых выполняется автозагрузка, достаточно освещена в других ответах. Однако, если у кого-то еще возникают проблемы с загрузкой, хотя пути автозагрузки были изменены по мере необходимости, тогда этот ответ пытается объяснить, в чем заключается магия этой вещи автозагрузки.
Так что, когда дело доходит до загрузки материала из подкаталогов, есть недочёт или соглашение, о котором вы должны знать. Иногда магия Ruby / Rails (на этот раз в основном Rails) может затруднить понимание, почему что-то происходит. Любой модуль, объявленный в путях автозагрузки, будет загружен только в том случае, если имя модуля соответствует имени родительского каталога. Так что, если вы попытаетесь вставить в lib/my_stuff/bar.rb
что-то вроде:
module Foo
class Bar
end
end
Он не будет загружен автоматически. Опять же, если вы переименуете родительский каталог в foo
, тем самым разместив свой модуль по пути: lib/foo/bar.rb
. Это будет там для вас. Другой вариант - назвать файл, который вы хотите загрузить, по имени модуля. Очевидно, что тогда может быть только один файл с таким именем. В случае, если вам нужно разделить ваши вещи на множество файлов, вы, конечно, можете использовать этот файл, чтобы требовать другие файлы, но я не рекомендую этого, потому что тогда, когда вы находитесь в режиме разработки, и вы изменяете эти другие файлы, Rails не может автоматически перезагрузите их для вас. Но если вы действительно хотите, вы можете иметь один файл с именем модуля, который затем указывает фактические файлы, необходимые для использования модуля. Таким образом, у вас может быть два файла: lib/my_stuff/bar.rb
и lib/my_stuff/foo.rb
, причем первый будет таким же, как указано выше, а последний содержит одну строку: require "bar"
, и это будет работать точно так же.
P.S. Я чувствую себя обязанным добавить еще одну важную вещь. В последнее время, когда я хочу, чтобы в каталоге lib было что-то, что нужно было автоматически загрузить, я начинаю думать, что если это то, что я на самом деле разрабатываю специально для этого проекта (что обычно бывает, это может когда-нибудь случиться) превратиться в «статический» фрагмент кода, используемого во многих проектах или в подмодуле git и т. д., и в этом случае он обязательно должен быть в папке lib), тогда, возможно, его место вообще не будет в папке lib. Возможно, это должно быть в подпапке в папке приложения. У меня такое ощущение, что это новый способ работы. Очевидно, что та же самая магия работает в тех местах, где вы используете пути автозагрузки, в которые вы помещаете свои вещи, так что это хорошо для этих вещей. Во всяком случае, это только мои мысли на эту тему. Вы можете не согласиться. :)
ОБНОВЛЕНИЕ: О типе магии ..
Как отметил Северин в своем комментарии, ядро «автозагрузка модуля» определенно является частью Ruby, но пути автозагрузки - нет. Вам не нужны Rails, чтобы делать autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar")
. И когда вы попытаетесь сослаться на модуль Foo в первый раз, он будет загружен для вас. Однако, что делает Rails, так это то, что он дает нам возможность автоматически пытаться загружать вещи из зарегистрированных папок, и это было реализовано таким образом, что нужно что-то предполагать в соглашениях об именах. Если бы это не было реализовано таким образом, то каждый раз, когда вы ссылаетесь на то, что в данный момент не загружено, ему нужно будет просмотреть все файлы во всех папках автозагрузки и проверить, содержит ли какой-либо из них то, на что вы пытались сослаться. Это в свою очередь победило бы идею автозагрузки и автозагрузки. Тем не менее, с этими соглашениями он может вычесть из модуля / класса ваши попытки загрузить, где это может быть определено, и просто загрузить это.