
Memoization in Ruby often looks harmless: def active? @active ||= compute_active_flag end ...
Memoization in Ruby often looks harmless:
def active?
@active ||= compute_active_flag
end
It’s clean. It’s idiomatic. It avoids duplicate work.
For years, this pattern feels safe.
But ||= does not mean “if unset.”
It means “if falsey.”
And in long-lived systems, that difference matters.
This:
@active ||= compute_active_flag
means Ruby assigns only when @active is nil or false.
So, since nil and false are the only falsey values in Ruby:
@active is nil -> compute@active is false -> compute@active is truthy -> reuseMemoization with ||= is only reliable when the memoized value is guaranteed to become truthy.
In one system I worked on, a boolean flag was memoized exactly like this.
At first, the flag was effectively “unset or true,” and everything worked.
Later, the domain evolved. false became an explicit, meaningful result based on new business rules.
That’s when it got strange:
compute_active_flag was expensiveThe code looked correct. The semantics weren’t.
That gap is where long-lived systems accumulate friction.
As systems mature:
nil)But ||= never changes its behavior. It keeps encoding a truthiness assumption that may no longer fit your domain.
This isn’t a Ruby flaw. It’s a reminder that convenience operators carry semantics.
If false is valid, but nil still means “unset”:
def active?
return @active unless @active.nil?
@active = compute_active_flag
end
If both false and nil are legitimate cached values, guard on definition instead using defined? (which is slightly faster, as it's evaluated by the parser rather than as a method call) or instance_variable_defined?:
def active?
return @active if defined?(@active)
@active = compute_active_flag
end
Now false and nil are preserved as cached results, and behavior matches intent.
It’s a few more characters. It’s also semantically honest.
Most issues in long-running systems aren’t dramatic failures.
They’re small mismatches between yesterday’s assumptions and today’s domain.
||= is a perfect example: convenient, idiomatic, and excellent in the right context.
But when false or nil becomes meaningful, tiny semantics compound.
Explicitness costs a little now. It usually saves much more later.
aiEvery developer tool follows the same pattern: parse flags, run logic, print output. git commit -m...
dockerAPT repositories are just HTTP file servers, doesn't seem like something that should require a custom piece of software.
opensourceWe wanted every employee in the company to use OpenClaw — not just engineers. Product managers...
azurefabricLeveraging Gemini CLI and the underlying Gemini LLM to build Model Context Protocol (MCP) AI...
googlecloudplatformLeveraging Gemini CLI and the underlying Gemini LLM to build Model Context Protocol (MCP) AI...
iacLeveraging Gemini CLI and the underlying Gemini LLM to build Model Context Protocol (MCP) AI...