In this article we’re going to explore the following topics:

the find library

library the Find module

module use case: counting the LOC of a Rails application

Before to start

I’m thrilled to share with you our latest project: Fun Facts about Ruby — Volume 1

Please feel free to spread the word and share this link! 🙏

Thank you for your time!

Introduction

Traversing a directory tree is a pretty common tasks in programming.

In Ruby, the find library is in charge of handling this task.

It’s a little-known but powerful and user-friendly library.

In this post, we’re going to explore the content of this library and use it for counting the LOC* of a Rails application.

*LOC = Lines Of Code

The find library

The find library is part of the Ruby Standard Library.

This means that this library is packaged with Ruby and it’s available when your Ruby setup is completed.

What’s the purpose of this library?

The find library aims to support the top-down traversal of a set of file paths.

So, let’s require this library

Feel free to read the Requiring a file or library in Ruby if you’re not familiar with the Kernel#require method in Ruby.

Here we can see that this library defines a new constant named as Find .

The Find module

This freshly added constant is actually a module

Indeed, we can see that the Find is an instance of the Module class — which is what we call a module in Ruby.

Feel free to have a look to the Modules in Ruby: Part II article if you’re not familiar with the class Module .

Also, it defines 2 module methods: Find.find and Find.prune .

Find.find

This method encapsulates the top-down traversal logic of a set of file paths.

Our directory tree

$> tree

.

├── file1.txt

├── directory/

│ └── file2.txt

├── another_directory/

│ └── file3.txt 2 directories, 3 files $> pwd

/Users/mehdi/workspace

The following script will display the content of this directory tree using the Find.find method

produces

/Users/mehdi/workspace

/Users/mehdi/workspace/another_directory

/Users/mehdi/workspace/another_directory/file3.txt

/Users/mehdi/workspace/directory

/Users/mehdi/workspace/directory/file2.txt

/Users/mehdi/workspace/file1.txt

Here, we call the Find.find method and we pass the path to our directory tree as argument.

Then we define a block that will be called for each encountered path during the top-down traversal of the /Users/mehdi/workspace path.

Each of these paths is passed as parameter of the block — the path parameter in this case.

Note that paths are provided in alphabetical order.

Find.prune

The Find.prune method is a kind of “control break” value.

When this method is called within the context of the Find.find method — so, within the block passed to this method — then 3 operations are processed:

1- the current file or directory is skipped

2- the loop restart with the next entry

3- if the current path is a directory path then the directory is not recursively traversed

Let’s have a look to the following example to illustrate this workflow

produces

/Users/mehdi/workspace

/Users/mehdi/workspace/directory

/Users/mehdi/workspace/directory/file2.txt

/Users/mehdi/workspace/file1.txt

Here, when the path points to the another_directory directory then the Find.prune method is called.

This operation results in not displaying /Users/mehdi/workspace/another_directory neither /Users/mehdi/workspace/another_directory/file3.txt .

In effect, when Find.prune is called then the directory path is skipped and the associated directory is not recursively traversed.

Counting the lines of code of a Rails application