Ruby’s first public release was in 1995. With the release of Rails in the mid 2000s, it surged in popularity just as I was finishing high school and starting a computer science degree (which I never finished) at the University of Victoria.
At the time, I was primarily interested in Python. I’d learned to write C as a teen because I wanted to make games, but had transitioned to Python and Pygame after getting tired of the legwork required to build things using SDL.
I definitely tried Ruby during its rise, but hadn’t seriously started doing any web programming, so I didn’t have much interest in it. The web programming I did back then was using Python or PHP.
When I started my professional career as a software developer, my first job was at a shop that built Shopify and Tumblr themes. They had basically no developer tooling, despite that a developer at a sister agency had built a really great framework on top of Middleman that made it much easier to work on Tumblr themes.
That project became my first real professional Ruby experience. I wanted us to be able to use more modern development tools, so I started trying to use the project and made my first ever open-source contribution to it. At the same time I was watching Gary Bernhardt’s Destroy All Software videos and was really excited by his test-driven approach to building software, even if I couldn’t imagine how I could apply it to the work I was doing.
Not long after we revamped our development tooling, I got my next opportunity in my Ruby journey: our company was tasked with creating an app for the Shopify app store. While the product was largely a frontend feature, we still needed a backend to handle the subscription management and integration with Shopify. I was tasked with that.
With almost no internal Ruby/Rails resources, I was able to build and deploy a simple Shopify app. I attempted to write tests for much of it, though I don’t remember being very successful.
Near the launch of that app, I caught a break and was offered a role by some friends from university. In my new role, I was a full stack Rails developer. One of my first tasks was to implement a payment gateway integration with GMO for a payment platform that was to power Steam’s launch in Japan. The shift from working solo on a tiny Shopify app to this project felt like going from riding a bike to driving an F1.
That project was very formative for me. I was working on a codebase built by very talented Rubyists, so the code (both production and test) in the project was a great reference for how to do things well. Additionally, I was entrusted with a large and important component that felt insurmountable to me, but the other devs at the company showed complete faith that I’d be able to make it happen (and they were right to.)
The project taught me a bunch of things. I learned that well designed and clear code is worth the effort, though I didn’t appreciate that I was learning that at the time. The project was exceptionally easy to work on and change compared to legacy projects I would work on later, especially given my lack of experience at the time.
I also learned that I was able to build big things by iterating and working incrementally. Building a payment gateway integration for a Japanese payment platform that had no English documentation and a reference implementation that was generated by Excel macros was a daunting task. Even with Google Translate, the docs were extremely hard to decipher. The reference implementation helped a lot, but I don’t know if you’ve ever read Ruby that was generate by Excel macros. Hopefully you haven’t. It’s not good.
I worked bit by bit, nailing down the pieces that I could get working and figuring out where the gaps were. When it came time to test the integration for real, everything worked. I found this both a relief and a triumph. It proved to me that I could build working software that was valuable to other people in the face of significant uncertainty.
Software development is not a practice where you learn how to do something and then do it. From a broad perspective, software developers spend the bulk of our timing trying to do things we haven’t done and learning systems that we don’t understand. Being handed a task which I couldn’t even start to grasp the scope of and completing it was the perfect experience to crystallize this idea for me.
Since that project I’ve launched online stores, helped bring warehouses online, revamped subscription systems, completed a variety of payment integrations (they’ve all been easier than that GMO integration), and more. The backend systems for those projects have all been in Ruby. (Okay, I admit it; I did write one backend in Elixir.)
Ruby has been a joy to use. Its clean syntax means your domain objects aren’t wrapped in boilerplate. Its object model and testing facilities allow you to lean into the best parts of object oriented programming. You can build elegant software with it, but when you need a quick hack, Ruby’s dynamism and introspection facilities make for wonderful escape hatches.
There has been more for me to learn at every step of this journey. I’ve always been able to find something to challenge me not to just write better code, but build better software more effectively. While everything in software is a tradeoff, sticking with Ruby is a decision that I’ve never regretted.