There is no Magic
When working with computers it’s easy to get overwhelmed with the complexity of it all. You write some code, run it through a compiler, and execute it on your machine. It seems like magic.
But when issues occur and things break down, it’s important to remember that there is no magic. These systems we work with are designed and built by humans like you, and that means that they can also be understood by humans like you. On every step, from the interface on the screen to the atoms your processor is built out of, someone considered how things should work.
I tend to work on two layers at the same time—the code I’m writing, and the ‘lower level’ code I’m using. I switch back and forth between my work in progress and the source code of the Ruby gem, the Go compiler, or even a disassembly if the source is not available. This gives me context about my dependency—are there comments explaining weird behavior? Is there a different function that I should be using mentioned in the code? Maybe an argument that wasn’t immediately clear from the docs, or even a glaring bug?
I find this context switching to be a sort of superpower: X-ray goggles for the software developer. You can look deeper many times: from your code, to the virtual machine running it, to the C language it’s written in, to the assembly that finally gets run. And even then you can read the Intel x86 manual to try and figure out what happens in the machine, and how the various instructions are encoded. Software systems are fractal in nature—every component a world in itself.
Of course, just because all these things are created by people like us doesn’t mean that it’s possible for one person to understand it all. We stand on the shoulders of thousands of giants, millennia of man-hours have been put into the systems to get to the point where we are today. It would take many lifetimes to deeply know every single step from atoms to GUIs, and that can be intimidating. But that doesn’t mean we shouldn’t try.
When you assume that the components we build our software on are mysterious scriptures that you can’t understand or change, then you will make uninformed decisions that don’t account for the actual situation. Instead, we need to be more clear-eyed. You need to work with the quirks of the underlying system and use them to your advantage, instead of paving over them.
So next time a library you use does something unexpected, take that extra step and pop open the hood. Poke and prod at the internals, look around, and make some changes. You will end up pleasantly surprised finding whole new worlds to explore and improve.