The following is a guest post by Logan Hasson and originally appeared on his blog. Logan is currently in the Ruby-003 class at The Flatiron School. You can follow him on Twitter here.
When running any Ruby application that contains more than one or two files, we generally find ourselves writing an environment.rb
file to handle all of the require
’s and require_relative
’s for us. And, to be frank, this gets to be a giant pain in the ass, especially when you want to include files in a particular order. Luckily, there is a better way! Or, I guess I shouldn’t say better, but way, way easier.
Let’s imagine we have the following directory structure.
Now, let’s say in our environment.rb
file, we want to include all of the subfiles in a_folder
, b_folder
, andx_folder
. To do this, we’d have to write a loop like this:
Essentially, it goes through the top level directory, skips any hidden files (those that begin with a period), finds everything that is a directory, and requires every file inside of each of them that isn’t a hidden file.
Phew.
I’ve written a puts
statement in every file in this directory that looks like this:
But each file has it’s own number in the puts
statement.
Let’s run environment.rb
and see what happens:
So it did what we expected…it included every file, and it did it in folder order. What happens, though, if everything working properly depended on the files in b_folder
loading before the files in a_folder
. Say, for instance, that the files in b_folder
make use of constants that are defined in files in a_folder
. We’d have to adjust our loop:
Here, we put the loop into a method, and make an array of the folders we want to loop through. By changing the order of the folders, we can change the order the files are loaded in. Here’s the output from running that:
So, it worked. But man, that still sucks. What if we had more subdirectories that depended on being loaded in a particular order? This would very quickly get out of hand.
And this is where Dir.glob
comes in handy. And makes you not hate loops. Everything we just did can be written in one line:
And our output?
That looks pretty darn identical to me! Sweet.
Dir.glob
is basically a regular expression matcher for file/directory paths. It doesn’t handle every regex you can throw at it, but it gets the job done for stuff like this way cleaner than our ugly loop. In this case, it iterates through each folder within the {}
and calls require_relative
every time it encounters a .rb
file. And if we wanted to, say, include files in a different order? It’s as simple as changing the order of the directories.
Pretty neat, eh? And while it’s functionally doing the exact same thing as our loop (it fact, it’s also a loop), I find it way simpler to read and far easier to understand. Gotta love easily-digestible one liners.