TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Don't overload #nil? in Ruby

90 pointsby prosaover 13 years ago

6 comments

bluesnowmonkeyover 13 years ago
Having recently worked with a Ruby codebase where anything could be nil at anytime, I consider even references to nil to be a code smell. Developers are inherently prone to ignoring error handling, so they'll happily ignore the fact that Order#customer really means Order#customer_or_nil. And when they see errors in production, they'll slap an andand on it and call it fixed. The code becomes extremely difficult to reason about.<p>I prefer that functions throw an exception when unable to do what they promised, rather than return nil or a null object. The try-catch block serves as documentation that the function might fail. If someone forgets to catch the exception, it will shut everything down rather than leave the program in an unanticipated state that could lead to an error elsewhere.
评论 #3220033 未加载
评论 #3220012 未加载
mcobrienover 13 years ago
I'm not sure I like it, but this works<p><pre><code> def nil.method_missing(*args, &#38;block); end </code></pre> So now you can call nil.whatever.you.like and get nil. It's also still falsy, but now every nil value in your app silently works and doesn't throw an error.<p>It's both impressive and scary that Ruby lets you (or that new contractor you're not sure about) change the fundamentals of the language in one line of code.
评论 #3219462 未加载
评论 #3219881 未加载
regularfryover 13 years ago
I've said this in a comment at rosania.org, but I think it bears repeating here: this is why we need a #blank? or #null? protocol that user classes can participate in as part of core. #nil? and an inextensible FalseClass just aren't enough to do the sorts of thing that Avdi was trying to do in his original post. My tentative proposal is languishing here: <a href="http://redmine.ruby-lang.org/issues/5372" rel="nofollow">http://redmine.ruby-lang.org/issues/5372</a>
jasiekover 13 years ago
I guess that overriding the behavior of any built-in classes in Ruby is not a great idea, as most gems rely on that unmodified behavior.
评论 #3220054 未加载
评论 #3221691 未加载
Confusionover 13 years ago
Conceptually, nil != false. You shouldn't use 'nil' to mean 'false'. You should always test explicitly for nil-ness using #nil?. If you write<p><pre><code> if finished? do_something end </code></pre> then finished? is not expected, and may not, return nil.<p>If you expect <i>some_value</i> to be able to be nil (which, for boolean values, is hardly ever), you should write<p><pre><code> if !some_value.nil? &#38;&#38; some_value do_something end </code></pre> In the end, these 'convenient' coercions that allow you to use any value as a boolean only come back to bite you, because unexpected stuff happens when stuff is unexpectedly nil. If it makes my coworkers cry that an object is nil and true at the same time, then they are at fault, not me.<p>Edit: and more importantly (I forgot to point this out explicitly) a non-nil value != true. That any string or integer is 'true' can lead to very hard-to-find bugs.
评论 #3219206 未加载
评论 #3219211 未加载
评论 #3219300 未加载
评论 #3219223 未加载
评论 #3219232 未加载
derefrover 13 years ago
Isn't this a flaw in Ruby, though? It also means that you can't create a delegate/decorator/proxy object for a false object and have it be false as well, which goes against the general "everything is determined by sending messages" vibe Ruby has going on.<p>I know the reasoning (it's much faster to do math on object IDs than it is to call a method), but there are workarounds for this (e.g. only allowing frozen objects to be boolean-false, and having the object's truth-ness/false-ness represented by the return value of its #false? method <i>at the time of freezing</i>—thus allowing the interpreter to locate it in a semantically-meaningful part of object-ID space that can later be masked for in a TEST instruction.)
评论 #3219415 未加载
评论 #3220046 未加载