Making sense of unfamiliar code
Tags: ruby, javascript, elixir, erlang
Published: 2019-03-06 05:51:55

---
title: Making sense of unfamiliar code
published: true
cover_image: https://thepracticaldev.s3.amazonaws.com/i/85fbdm2k4kgoukmgcuw4.jpg
description: Reading code is as important a skill as writing code, possibly even more.
tags: ruby, javascript, elixir, erlang
---
We all want to get better at writing code, right?
But what about *reading* code?

We spend more time reading code than writing it, so it's worth improving.

Plus, the better we are at reading, the more ideas we have access to. That ends up improving the code we write too.

It's a re-enforcing loop.

## Outside-inside approach

When encountering unfamiliar code, it's a good idea to start by understanding the edges first, and then working inwards. It's like solving a puzzle.

The best way to solve a puzzle is to find pieces with the least collaborators (corner pieces) and then sort out pieces with the most collaborators (middle pieces).

![Puzzle pieces](https://thepracticaldev.s3.amazonaws.com/i/ksmpgyc65icy4o1oizld.png)

For example, in a web app, you can think of a corner piece as the **routes** (entry point) or the **database schema** (exit point). 

The inner pieces are the parts that have more collaborators like controllers and models.

## Reading the code

With this approach, a good order for examining a web app would be:

1. **Dependencies**: `Gemfile`, `package.json` or `mix.exs`
2. **Inputs**: routes or GraphQL definitions
3. **Outputs**: database schema definition or external API calls
4. **Algorithms**: models, controllers, classes, or modules

## Reading a file

It's a similar approach for reading files. Start outside, work your way inwards:

1. **Dependencies**: `import`, `include` or `require`
2. **Inputs & Outputs**: the API of the module or class, parameters and return values
3. **Algorithms**: function bodies (the middle)

Focus on smaller files before big files. Smaller files are either dependencies of bigger files or have fewer collaborators. That makes them easier to understand.

Just like life, start small and then work your way up.

Here's how to find the shortest files:

```bash
# find shortest files by extension
wc -l $(find . -name *.js) | sort -n
```

# Tests

Take a look at the tests. They show all the entryways with examples of input params and expected outputs. They are invaluable.

# Tinker mode 

As you go along, you can re-enforce your learning by tinkering in the REPL.

In Rails that means dropping into `rails console`, in JavaScript use `node --require index.js` and in Elixir `iex -S mix`.

# Debug it

Use a debugger to step thru the code. It's a great way to see the critical pathways in action.

You can do that in Ruby with `binding.pry` or `byebug`, in JavaScript use `ndb`, or if you're using a concurrent language like Erang/Elixir check out `observer:start()` or `sys:trace(pid, true)`.

Familiarizing yourself with the debugging and tracing tools of your language is an investment that always pays off.

## Conclusion

Reading code is a skill, and that means it requires practice to improve.

Don't worry if you don't understand everything the first time. Partial understanding is on the road to full understanding.

Happy code-reading!