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.

← All articles