Yes, I thought of that too. But of course to me that is *why* I would
check for nil (I really really do want to know if it's nil).
Maybe the poster just didn't know what he was talking about... m.
···
Roger Pack <rogerpack2005@gmail.com> wrote:
matt neuburg wrote:
> A post I ran across on a rails forum reads:
>
> "Warning! DO NOT test for nil! This is a very bad coding practice. You
> can use "if obj", but do not use "if obj.nil?" or whatever."
>
> Is that generally true? Why? m.
"Warning! DO NOT test for nil! This is a very bad coding practice. You
can use "if obj", but do not use "if obj.nil?" or whatever."
Is that generally true? Why? m.
because it might be false [not nil]?
Technically yes, but that admonition has more meanings (some of which may have escaped that original rails poster).
Consider this pattern:
if @user
render :partial => 'premium_content' # for logged-in users
else
render :partial => 'teaser_content' # for the great washed masses
end
That is sloppy programming because it asks @user for its type (are you a logged-in user? or just a slovenly nil?)
The correct pattern is @user is never nil, and if no user is logged in, then it should hold a "Guest" object. Then User and Guest can provide different methods for the same messages (method names):
render :partial => @user.content_template
That pattern collects many redundant 'if' statements into one place; that technique is the heart of all OO programming.
"Warning! DO NOT test for nil! This is a very bad coding practice. You
can use "if obj", but do not use "if obj.nil?" or whatever."
Is that generally true? Why? m.
because it might be false [not nil]?
Yes, I thought of that too. But of course to me that is *why* I would
check for nil (I really really do want to know if it's nil).
Definitely use #nil? if you want to know whether something is exactly nil. There are certainly a lot of unnecessary calls to #nil? out there, but it doesn't follow that it can never be right to test for nil.
Definitely use #nil? if you want to know whether something is exactly nil. There are certainly a lot of unnecessary calls to #nil? out there, but it doesn't follow that it can never be right to test for nil.
Let's call this the "non-suicidal Samurai Principle". Either return victorious, or return empty-handed. (And don't waste my expense training you, duh!)
How many times have we written...
def samurai
blah and blah or blah
end
if samurai
...
...and then never bothered to check - even with unit tests, whether a failing samurai() call returned a nil or a false? Ruby's break with incorrect tradition - letting 0 be true - cleaned up a whole lot of clutter. .index() can easily distinguish "found at 0 index" from "not found". But this means we no longer always need to track which of those blah() calls returns a nil, which a false, and which one the boolean short-circuiting collects for us.
Definitely use #nil? if you want to know whether something is exactly
nil. There are certainly a lot of unnecessary calls to #nil? out
there, but it doesn't follow that it can never be right to test for nil.
Let's call this the "non-suicidal Samurai Principle". Either return
victorious, or return empty-handed. (And don't waste my expense training
you, duh!)
How many times have we written...
def samurai
blah and blah or blah
end
if samurai
...
...and then never bothered to check - even with unit tests, whether a
failing samurai() call returned a nil or a false? Ruby's break with
incorrect tradition - letting 0 be true - cleaned up a whole lot of
clutter. .index() can easily distinguish "found at 0 index" from "not
found". But this means we no longer always need to track which of those
blah() calls returns a nil, which a false, and which one the boolean
short-circuiting collects for us.
I didn't say you should always do it, simply that if you want to know whether an object is exactly nil, use #nil?. If you don't, don't
There's an interesting case of nil overloading that I've never seen any very nice workarounds for, though it probably occurs rarely if at all:
a = [1,2,3,nil,"abc"]
r = a.find {|e| !e }
r will be nil -- but it will also be nil if a doesn't contain nil. Fortunately not an everyday problem, but an interesting case of difficulty distinguishing found from not found.