When googling to find the answer to a ruby (or rails) coding problem, it struck me that code snippets always use “require” to include any necessary libraries. For example, I recently searched for a way to compare IP addresses using CIDR notation. (I had IP ranges stored in CIDR notation and wanted to see if the user’s IP was in the range.)
After hunting around, I came up with this solution:
require 'ipaddr' admin_ip = IPAddr.new('192.168.1.0/24') client_ip = IPAddr.new('192.168.1.2') admin_ip.include?client_ip => true # Do it in one line: IPAddr.new('192.168.2.0/24').include?IPAddr.new('192.168.2.100') => true
Using require in this code snippet is clear and it makes lots of sense to show it this way. You can see immediately that the code is dependent on the ruby IPAddr library. But in real code, you should never use require to include libraries or other files.
Best Practice: Use Autoload Instead of Require
Instead of using require, you should use autoload. And furthermore, you should never put the autoload statement in middle of your code, as might implied by typical snippets. Includes should always happen at the top of any file. For example, looking at a ruby file some_class.rb:
autoload :IPAddr, 'ipaddr' class SomeClass # returns true if ip_check is contained in ip_master range (CIDR notation) def check_ip(ip_master,ip_check) IPAddr.new(ip_master).include?IPAddr.new(ip_check) end end
Why use Autoload instead of Require?
So, why use autoload instead of require? Because require loads the file immediately when ruby processes the require line. Autoload, on the other hand, doesn’t load the file until you try to access the symbol defined in the autoload statement. If you don’t accesses it, it doesn’t get loaded and you eliminate any unnecessary overhead processing.
But autoload uses require under the hood. So just like require, autoloaded files are only included once. By comparison, using ‘include’ would load and include the file every time.
Why Put Autoload at the top of the file?
This is just a best practice. You don’t want to hide dependencies buried deep within a method. When I open a file, I want to see the dependencies right away. This makes code maintenance and debugging much less error prone – especially if you are working on a project with multiple engineers or returning code you wrote last year.