Require? Require_all? Require_relative?
Two weeks ago was projects week and it felt like the rspec training wheels coming right off. I realized that one of the things I had taken for granted was setting up my project directory. I had gotten comfortable with copy and pasting require or having it already written in my files, I wasn?t sure whether I really understood the method and other methods similar to it. When do I use require? require_all? Or require_relative?
What is require?
require is a method that is used when you want to reference and execute code that is not written in your current file. The method takes in a path in the form of a string as an argument and there are two ways the string can be formatted ? either as an absolute path or a shortened name.
# absolute pathrequire ‘./app/example_file.rb’# shortened namerequire ‘example_file’
Shortened string vs. Absolute paths?
Because programmers are always looking for the most efficient way to write code, the shortened string option is oftentimes preferred. The shortened strings always depend on the listed directories in $LOAD_PATH. $: is a global variable that is used for looking up external files. You may see this used in your bin/environment.rb like this:
# bin/environment.rb$LOAD_PATH << ‘./app’
Other than it being a shortened way to write code, the shortened string option is preferable to the absolute path because if you decide to move your .rb file into a different folder, the require ‘./somewhere/absolute_path.rb’ method would return false and it would not load your file, until you manually change the path. Listing your directory in $LOAD_PATH allows for flexibility and could load your external file even if you were to move it into a different folder. Let?s see how $LOAD_PATH loads the directories:
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
You thought you got it, but?
So now that we figured out what require does, we may be wondering when to use require, require_relative, and require_all. What I?ve noticed after scanning through several labs over the last few weeks was thatrequire is usually called when requiring gems loaded in gemfile. Though require can be used to both execute gems and external dependencies, the preferable method to load relative paths is require_relative. require_relative is a subset of require and is a convenient method to use when you are referring to a file that is relative to the current file you are working on (basically, within the same project directory).
So why would you want to use require_relative over require? While require relies on the directories loaded in $:, therequire_allgem allows you to execute code from other files without having to shovel in directories beforehand. The general rule of thumb is require should be used for external files, like gems, while require_relative should be used for referring to files within your directory. Though you can call on absolute paths using both methods, but require_relative’s scope is wider and is aware of the entire directory where the program resides. Technically, require could be called on to work like require_relative:
# clunkyrequire(File.expand_path(‘path_here’, File.dirname(__FILE__)))# cleanrequire_relative(‘path_here’)
Looking at the snippet above, require_relative is a more efficient option when calling on files.
How about require_all? This method is also a subset of require and is also a convenient method that does the work that File.dirname(__FILE__) does. The method allows you to require the entire directory. Once you install the require_all gem, you can require ‘require_all’ to transform your clunky require(File.dirname(‘lib’) into require_all ‘lib’ which will ?magically? refer to the files in the lib directory!
Require and ?all? of its ?relatives?
In conclusion, reserve require for gems and take advantage of therequire_relative and require_all gems when referring to files for efficiency.
sources: https://www.thoughtco.com/requre-method-2908199 https://apidock.com/ruby/Kernel/require http://www.rubydoc.info/gems/require_all/1.3.0 https://stackoverflow.com/questions/837123/adding-a-directory-to-load-path-ruby