DEV Community

Cover image for Making sense of unfamiliar code
Joshua Nussbaum
Joshua Nussbaum

Posted on • Edited on

Making sense of unfamiliar code

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

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:

# find shortest files by extension
wc -l $(find . -name *.js) | sort -n
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (0)