3 ms·
I agree: don't autoload lib. Even better: Autoload discrete subdirectories in lib occasionally. Occasionally? If something is a library, why do you want auto
by chao- 3y ago
I agree: don't autoload lib.
Even better: Autoload discrete subdirectories in lib occasionally.
Occasionally? If something is a library, why do you want autoloading anyway? The likely answer is that you are actively working on it, and autoloading allows quick feedback loops, and is a huge productivity boost.
I would expect a "library" is a true, cross-cutting technical dependency, not behavior for the application domain (or else it ought to be in app). It is safe to autoload some number of things inside of lib some of the time, if you knowingly placed it there. One manner of achieving this:
- Be specific, and don't use a wildcard or globbing notation. Maintain a list of exclusive sub-directories in lib that are capable of optionally being auto-loaded (in development only).
- Set up an environment variable that controls when and which of these curated lib subdirectories are be autoloaded. Only enable one when actively working on it, keep disabled otherwise.
As with many things in Rails, there are (a) a dozen other ways to achieve a very similar result, (b) people with different aesthetic preferences for one or the other, and (c) other people who chafe at there not being a "blessed" way to do this, or even think that making one's own conventions ought not be done.
- nightpool 3y ago> If something is a library, why do you want autoloading anyway? What? Bundler always "auto-loads" all of your gems automatically anyway—that's the whole point of the require: statement. If anything, thinking about lib/ code as library code makes it MORE obvious that it should be autoloaded—why should gem "papertrail" and lib/papertrail.rb ever behave any differently? Both should provide Papertrail constants to the rest of the application.
- chao- 3y agoI think we are using "autoload" to discuss different things, one of which is probably in line with what the article is about, and the other is not. And I may be the one misreading here! I take "autoloading" in the Rails context to mean "Rails.application.config.autoload_paths", which is separate from a Ruby "require", and which has always had all sorts of complexity, but is supposed to be recommended against as of Rails 6. You are, I believe, referring to "require" call to load a library once (which is what Bundler does). The Rails autoloading (once homegrown, now via zeitwerk) is used to hotswap to a new version of a constant when a file has changed. It does so by searching for missing constants on the file system based on "root paths", in this case using "config.autoload_paths" plus a few defaults. This hotswap nature of autoloading is why I reference autoloading a library specifically in the context where one is "actively working on it, and autoloading allows quick feedback loops". A simple "require" does not do that. It loads the library once, ala Bundler, and unless it lives in the tree of an autoload "root path", changes will not be available until one restarts the server/console/rake task, etc. I agree that, of course, that one's libraries ought to be loaded via "require" to be used. Otherwise, they are dead code, and might as well not be part of the project source. My suggestion of an ENV var is that it should swap from a single require at application boot to live autoloading.