ruby / philosophy
These articles describe my Ruby style at the end of 20 years of writing Ruby, from 2006 to 2026. I ported the last codebase I worked on from about 200,000 lines of Ruby to Go.
My approach
I wrote small Ruby I could hold in my head. A Rack app instead of Rails. Plain SQL instead of an ORM. Thin HTTP clients instead of vendor SDKs. A custom test framework. A restricted Haml subset for HTML templates.
My feeling is that each dependency is an interface to learn and a security surface to patch. A small codebase contains only what it uses, so when something breaks, the stack trace points at my code.
Why I moved to Go
I moved to Go for reasons much like the reasons I wrote minimal Ruby. Go takes some of them further.
Performance. The rewrite cut page response times across the application.
Type-checking. A compiler catches at build time what Ruby left for runtime, or for production.
Object-orientation. My Ruby was barely object-oriented: most of
lib/ was plain objects with an initialize and a call. Go fits
that shape. It has no classes or inheritance, only structs,
methods, and small implicitly-satisfied interfaces. The style I had
settled into was the style Go prescribes.
Error handling. Go returns errors as ordinary values checked
where they happen, so every failure path is explicit. Ruby's
begin/rescue/end lets exceptions travel up the stack invisibly.
Tooling. goimports, go vet, and the race detector ship with the
language.
Security. Fewer third-party dependencies leave a smaller security surface. The thin-client instinct is native to Go, whose standard library covers HTTP without a gem.
Dependencies. Go modules are version-pinned and verified against a checksum database. https://rubygems.org serves mutable gems from a single registry. My thin-client habit was partly a reaction to that supply chain. Go answers that risk at the language level.
AI agents. A typed, formatted, tool-rich codebase is easier to drive with programming agents. They get compiler feedback as well as test failures, and a smaller surface to reason about.
The Go versions of this work live under go / postgres, go / job-queues, go / web framework, and go / html templates.