When nothing isn't

One of the strangest things for me, coming from the “C” world to Ruby
was how much attention “nil” gets. Sure, NULL is there in C, but it’s
about as interesting as its value.

In Ruby, it seems as if nil is an extra value, stuffed in somewhere
around zero, but not really there or anywhere else. It seems to be
almost ubiquitous in Ruby. Quite strange for something that is so close
to non-existent.

When writing rails, I find myself experimenting with various and sundry
ways of checking for nil and not really satisfied with any of them. I
would like to find out from the group here what are the most standard
ways to check for nil in a couple of common situations.

One of the most common for me seems to be that of a session key that I
want to do something with but I have to make sure it is not nil first.
Let’s say we have a session key that is expected to have an array in it,
and we want to check the size of the array, I wind up using a trinary:

the_size = (session[:somethingorotherarray].nil?) ? 0 :
session[:somethingorotherarray].size

Is there a more graceful way of doing that? I keep ending up with a
bunch of those and also if statements with
(!session[:somethingorotherarray].nil?). Looks really ugly to me.

Do others use “defined?” more often, and can you use that on a session
key? Just seems like I’m working harder at avoiding nothing than I
should. How are the rest of you dealing with nothing of this variety
and other types of nothing that happen along frequently in a Rails app?

thanks,
jp

On 3/16/07, Jeff P. [email protected] wrote:

the_size = (session[:somethingorotherarray].nil?) ? 0 :
session[:somethingorotherarray].size

Is there a more graceful way of doing that? I keep ending up with a
bunch of those and also if statements with
(!session[:somethingorotherarray].nil?). Looks really ugly to me.

So factor it out.

def my_something
@my_something ||= (session[:somethingorotherarray] || [])
end

def my_something=(s)
@my_something = session[:somethingorotherarray] = s
end

Now if it’s not defined in the session you’ll get a blank array back.

It’s a pretty basic principle…if you see duplication, factor it out.

Pat

p.s. it’s definitely not a good idea to stick a full array of objects
in the session…at most you’d want a string/array containing the IDs
of objects

I would dispute the notion that NULL or \0 are uninteresting in C. But
that’s
not the question.

The Ruby language defines the value of an unset hash member as nil.
Therefore,

my_hash[:bogus_key] == nil => true

Further, Ruby defines the behavior of nil in a conditional as evaluating
to
false, e.g.:

if nil
puts ‘it is nil’
else
puts ‘it has a value’
end

The session key deal is typically done as:

login_id = session[:user] || 0

Where the || conditional assignment provides some sensible default.

HTH

Wes G.-2 wrote:

the_size = (session[:somethingorotherarray].nil?) ? 0 :

thanks,
jp


Posted via http://www.ruby-forum.com/.


View this message in context:
http://www.nabble.com/When-nothing-isn't-tf3417890.html#a9525946
Sent from the RubyOnRails Users mailing list archive at Nabble.com.

Thanks guys. The session[:unknown_key] == nil == false thing will help
clean up a lot of my code, but we’re still left with the ugliness of
having to separately test something for nil before applying a method.

My example was .size on something that is expected to be an array.

Is this legal?
(my_maybe_nil_array || []).size

irb to the rescue:
irb(main):002:0> myhash = {}
=> {}
irb(main):003:0> myhash[:foo]
=> nil
irb(main):004:0> (myhash[:foo] || []).size
=> 0

So what do you guys think, is that an ugly construct, or is it a
reasonable way to call a method on something that might be nil (assuming
zero is a good default value for the whole mess)?

thanks,
jp

Jeff P. wrote:

ways of checking for nil and not really satisfied with any of them. I

Is there a more graceful way of doing that? I keep ending up with a
bunch of those and also if statements with
(!session[:somethingorotherarray].nil?). Looks really ugly to me.

Do others use “defined?” more often, and can you use that on a session
key? Just seems like I’m working harder at avoiding nothing than I
should. How are the rest of you dealing with nothing of this variety
and other types of nothing that happen along frequently in a Rails app?

A hash will return nil if you try to access it with a non-existent key:

irb(main):001:0> hash = Hash.new
=> {}
irb(main):002:0> hash[:blah]
=> nil

This allows you get to rid of those .nil? methods on hashes if you don’t
like them.

There is also “||=”. As in:

irb(main):003:0> hash[:size] ||= 0
=> 0
irb(main):004:0> hash[:size] ||= 10
=> 0

which is the equivalent of

hash[:size] = hash[:size] || 0

so you could do something like:

irb(main):018:0> hash = {}
=> {}
irb(main):019:0> size = (hash[:size] ||= 10)
=> 10
irb(main):020:0> size
=> 10
irb(main):021:0> hash[:size]
=> 10


Michael W.

I’d be more tempted to write:

myhash[:foo].size rescue 0

Wes G.-2 wrote:

Is this legal?
So what do you guys think, is that an ugly construct, or is it a


View this message in context:
http://www.nabble.com/When-nothing-isn't-tf3417890.html#a9526876
Sent from the RubyOnRails Users mailing list archive at Nabble.com.

the_size = (session[:somethingorotherarray].nil?) ? 0 :
session[:somethingorotherarray].size

Is there a more graceful way of doing that?

Sure, just do:

(session[:foo] || []).size

I keep ending up with a
bunch of those and also if statements with
(!session[:somethingorotherarray].nil?). Looks really ugly to me.

It’s not really that ugly to me! You can drop the inverse operator (!)
if you use the ‘unless’ conditional instead if you want:

unless session[:foo].nil?

run some code

else

do something else

end