On Sat, Apr 5, 2008 at 6:13 AM, David A. Black
The false value isn’t handled incorrectly, though.
When I wrote “handled incorrectly”, I didn’t mean that Ruby handles it
incorrectly; I meant that I’ve seen a great deal of code people had
written which was incorrect in the face of explicit ‘false’ values
because of this very common misunderstanding of ||=.
The test is for
boolean falseness, and both nil and false always pass that test. If
you need x to be a certain value (nil or any other), you should test
for exactly that value.
I agree. Which is why I often use something like
if x.nil? then x = y end
which isn’t nearly as concise and expressive as x ||= y. It could be
somewhat shortened to:
x.nil? && x = y
but I don’t find that particularly readable. In any case, neither
of them conveniently handles the case where x is undefined as well as
the case where x is nil, the way ||= does, as you note below:
Also, it’s not exactly that the lhs of ||= is nil. ||= will allow
uninitialized local variables, which are not nil:
So we’d be getting into a thing with “uninitialized or nil, but not
false” which seems very use-case specific to me.
The core of my argument is that this idiom isn’t rare or use-case
specific at all. is, in my experience of both writing and reading Ruby
code, an extremely common pattern. Being able to concisely and
unambiguously say “after this line, x (or h[:x]) is guaranteed to be
initialized and non-nil, either by previous assignment or by the
specified default” is something I see a need for every working day.
And because it’s such a common need, and because ||= seems so
deceptively close to fulfilling it, I have seen many, many examples of
code that was subtly incorrect because it used ||=. Ruby is a
language that often offers sugar for common idioms, and this is a very