I have been on a journey for some time now. It started when I was a 8 year old kid who decided to take his Dad’s Betamax apart to see how the movies got in there. It continued when I was 10 and I got a Commodore and played tape-drive games like Red Baron. My future was forever set in stone when I arrived at a new Jr. High School @ 13 and they had AppleIIes in my home room, math lab, and computer lab.
I would obsessively play Zork and more than anything, I wanted to know how to write such a game. I didn’t get very far on that front, but I did start writing BASIC. I took anything that resembled a computer class, or even a class which had computers in it. By them we had some clone IBM at home, and there I would POKE sounds out and obsessed with learning more.
I am nearly 40 now. In a couple of years I will not be the young crazy guy I once was. I will be a middle-aged life-long programmer. And honestly, shit ain’t so bad yo. I couldn’t be happier. But enough about me, let’s get to my secret for writing solid ruby code that always gets an A on CodeClimate, and rarely has bugs. My secret for writing Ruby code that is easy to extend and change.
The secret is… there is no secret. I am a sponge. I find great programmers and I suck them dry for knowledge. When no one can teach me anything where I am. I move on.
I watch 2-3 videos A DAY on programming, many of the times I have already seen it several times, and I instead play it in the background and listen while I code. I code all the damn time. Ask my fiancée. I stay up till 4am coding and neglect spending time with her all the time. I practice the shit I gleam from smart guys and gals.
Many of the times what I read and watch isn’t even about Ruby. It is on Scala, LISP, or Python. I will name a few heroes now.
- Gary Bernhardt - this guy is my fucking hero. Seriously. No one had made me change my style of coding more than Gary.
- Jim Weirich - any one who has emailed this amazing man knows what it is like to converse with a kind gentle mental giant.
- Ben Orenstein - he made me Vim and then really Vim. He taught me to do all kinds of shit he will never remember teaching me.
- Phil Cohen - this guy is a personal friend and colleague and is my surrogate neck beard - when he speaks I listen
On to the real matter here. My manifesto for beautiful Ruby code! Before I begin sharing it I need to hedge one thing to prevent the hate mail. I was raised Evangelical and am now a non-theist. I am not a dogmatic guy. However I am a huge science nut, and process and evidence are my guide. Sometimes a rule needs to be bent a bit. So there, I said it - use your head to determine how much you want to consume here. I go whole-hog most of the time and it serves me well.
My Manifesto for Beautiful Ruby Code
Prefer the Functional side of life
Functional programming has changed my life. Seriously. Over the years, state and sloppy code have invaded my sleep and caused me to relive terrible cubicle experiences in my dreams for hours a la groundhog day. Shying away from state was one of my first a-ha! moments that actually led me to sleeping better at night.
Prefer enumeration to loops
I wrote loops for years. I also had a lot of endless loops happen. Loops are a low level construct that I thought were impossible to live without. Then I met Ruby. I haven’t written a loop in a long time…. (except for in Clojure, or the blocking, network type)
Enumeration is the iteration over a collection of items. It is superior for many reasons, one is that it is bounded on the collection limits, so you don’t get endless loops.
Enumeration as a design decision means that functions will likely be built out of more lambads, and approximating to a value. More on that later though.
Prefer immutability and value objects
State is our enemy as programmers. The wild west of exponential growth in processor speeds is long gone, and has been replaced by cores. Cores have been Ruby’s Achilles’ heel for some time, but no more. You will need to step out of MRI, but thats ok when you see what you gain.
When objects you create don’t mutate, but instead you get a copy of that object with some modifications made, you are writing code that works like Git. You can walk objects forward and backward like an audit log. It is sort of like time travel.
Value objects are everywhere and you use them all the time. They are simply something that is not defined by it’s identity, but by it’s value. I can have five 1’s in a method, does it matter if they are this instance or that instance? Nope, they are still 1s.
What about Strings? Is “super” equal to “super” even if you set one to a local variable, a and the other to a local variable, b? They will not have the same object_id, but an == comparison says they are the same. Value objects make life simple.
Prefer polymorphism over conditional, imperative logic
Conditional logic sucks. I have been writing ifs for so many years, I thought that life was impossible without them. The first time someone told me they could usually be avoided I thought he was nuts. By the way, it was the same guy who introduced me to Ruby. He knew this shit a long time ago and we are only just catching on as a community. Those damn small talkers seem to have a time machine….
The more conditional paths in a method you have, the harder it is to test, and there are more places for code to grow and grow by people adding this case and that case all into one method. It is like leaving sugar out on the counter to start an ant invasion.
I will write much more on Polymorphism in the near future.
Prefer the explicit to the imperative
This one took a long time to get my head around. It is still hard to explain. I think it is still easier to show what it is:
Of course, I still advocate IMPLICIT returns. :)
Prefer laziness over large memory operations
Let’s say you have a dataset, be it a file, or collection or whatever, but it is really big. Anything over a few megs really. But to make the problem more apparent, exaggerate that to several gigs. Now try to load the Ruby that open that file when it looks like:
You will quickly run out of memory…. Now if that was on a server with lots of memory, and you have multiple processes trying to gobble files….. Yeah, it’s a bad spike and then a huge flatline…. And all because you just wanted 10 lines!!!
Instead, be lazy..
That is all for today. I am putting together some screencasts to show this style in action and I am open to doing live coding sessions on a hangout if enough people are interested in seeing it.
If this topic interests you enough that you would like to see me do a "Peepcode play by play" style live coding session discussing these principles, please vote @ the link below:
Here are some examples of code that fit my manifesto and you can see their grades yourself.