[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

why not check for nil?

matt

2/21/2009 4:58:00 PM

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.

--
matt neuburg, phd = matt@tidbits.com, http://www.tidbits...
Leopard - http://www.takecontrolbooks.com/leopard-custom...
AppleScript - http://www.amazon.com/gp/product/...
Read TidBITS! It's free and smart. http://www.t...
6 Answers

Roger Pack

2/21/2009 5:37:00 PM

0

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.

because it might be false [not nil]?
-=r
--
Posted via http://www.ruby-....

matt

2/21/2009 6:09:00 PM

0

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.
>
> 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).

Maybe the poster just didn't know what he was talking about... m.

--
matt neuburg, phd = matt@tidbits.com, http://www.tidbits...
Leopard - http://www.takecontrolbooks.com/leopard-custom...
AppleScript - http://www.amazon.com/gp/product/...
Read TidBITS! It's free and smart. http://www.t...

Phlip

2/21/2009 6:12:00 PM

0

Roger Pack 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.
>
> 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.

--
Phlip

David A. Black

2/21/2009 6:39:00 PM

0

Hi --

matt neuburg wrote:
> 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.
>> 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.


David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.r...
Coming in 2009: The Well-Grounded Rubyist (http://manning....)

Ruby Training Atlanta! April 1-3, http://www.entp.com/training...

Phlip

2/21/2009 7:29:00 PM

0

David A. Black wrote:

> 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.

--
Phlip

David A. Black

2/21/2009 8:19:00 PM

0

Phlip wrote:
> David A. Black wrote:
>
>> 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.


David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.r...
Coming in 2009: The Well-Grounded Rubyist (http://manning....)

Ruby Training Atlanta! April 1-3, http://www.entp.com/training...