ruby / philosophy
These Ruby articles describe my Ruby style at the end of my time writing Ruby over a 20 year period from 2006 to 2026. I ported the final codebase I worked on from ~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
The reasons I wrote minimal Ruby are similar reasons I moved to Go although Go takes some things further.
Performance. The rewrite significantly reduced 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, with no classes or inheritance, just 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 improve the security posture. 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, and Go answers it at the language level.
AI agents. A typed, formatted, tool-rich codebase is easier to drive with programming agents. They get compiler feedback, not just 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.