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.
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).
With Rails, I believe it depends on what you want to do.
If you use Bundler, you can assume your gem has been 'required' (you can of course override what is required with the :require option).
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).
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.
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).
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).
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_relative
is the way to go in 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).
Another solution would be to define these constants in your main file, it would also give you an idea of the structure.