# Using the spaceship operator to compare nil?

**URL:** <https://www.ruby-forum.com/t/using-the-spaceship-operator-to-compare-nil/111693>\
**Category:** Ruby\
**Created:** [August 9, 2007, 9:20pm UTC](https://www.ruby-forum.com/t/using-the-spaceship-operator-to-compare-nil/111693 "2007-08-09T21:20:52Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![thechak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/aeb1de/32.png) [@thechak](https://www.ruby-forum.com/u/thechak)\
**Post date:** [August 9, 2007, 9:20pm UTC](https://www.ruby-forum.com/t/using-the-spaceship-operator-to-compare-nil/111693/1 "2007-08-09T21:20:52Z")

</div>

Hey folks,

I have a test helper in a Rails app called assert\_ordered\_by

def assert\_ordered\_by(attribute, collection, direction)  
collection = collection.to\_s  
return true if assigns[“#{collection}”].length \< 2  
option\_one = assigns[“#{collection}”][0].send(attribute)  
option\_two = assigns[“#{collection}”][1].send(attribute)  
assert option\_one.send(direction, option\_two), “#{option\_one} is not  
#{direction} #{option\_two}”  
end

It works well in all the cases I’ve tried thus far except when dealing  
with nil. I want to teach the method to treat nil the same way SQL  
treats NULL because the collections will often contain ActiveRecord  
objects.

I have the idea in my head that I need to use the spaceship operator  
(\<=\>) to do this, but am unsure about how…

Any ideas?

Thanks,  
Dan C.

> **[Design and Development agency building web and mobile products - thoughtbot](https://thoughtbot.com/)**
>
> Look for a nearby developer? Hire thoughtbot, a design and development agency to provide design and development services for mobile and web applications.

---

<div class="post-metadata">

**Author:** ![thechak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/aeb1de/32.png) [@thechak](https://www.ruby-forum.com/u/thechak)\
**Post date:** [August 9, 2007, 11:32pm UTC](https://www.ruby-forum.com/t/using-the-spaceship-operator-to-compare-nil/111693/2 "2007-08-09T23:32:08Z")

</div>

I forgot to mention that this is called, for example, with:

assert\_ordered\_by :last\_name, :users, “\<=”

I’m also moving away from using the spaceship operator into  
conditional logic land because I was having difficulty dealing  
(mentally) with comparing nil to various types (dates, strings,  
integers, etc.). Here’s the latest non-working code… 😕

def assert\_ordered\_by(attribute, collection, direction)  
collection = assigns["#{collection.to\_s}"]  
return true if collection.length \< 2  
collection.sort do |a, b|  
if a.nil? && !b.nil?  
return false if direction.include?("\>") # nil cannot be  
greater than anything except another nil  
elsif b.nil? && !a.nil?  
return false if direction.include?("\<") # nil cannot be  
greater than anything except another nil  
elsif !a.nil? && !b.nil?  
assert a.send(attribute).send(direction, b.send(attribute))  
elsif a.nil? && b.nil?  
return true  
end  
end  
end

---

<div class="post-metadata">

**Author:** ![thechak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/aeb1de/32.png) [@thechak](https://www.ruby-forum.com/u/thechak)\
**Post date:** [August 9, 2007, 11:40pm UTC](https://www.ruby-forum.com/t/using-the-spaceship-operator-to-compare-nil/111693/3 "2007-08-09T23:40:10Z")

</div>

On 8/9/07, Dan C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I forgot to mention that this is called, for example, with:
> 
> assert\_ordered\_by :last\_name, :users, “\<=”
> 
> I’m also moving away from using the spaceship operator into  
> conditional logic land because I was having difficulty dealing  
> (mentally) with comparing nil to various types (dates, strings,  
> integers, etc.). Here’s the latest non-working code… 😕

Try this:

has\_nil, doesnt = collection.partition { |r| r.send(attribute).nil? }

you can then sort only the ones that have a meaningful sort value and  
then rejoin as needed based on the direction, e.g. for one directed  
you want:

doesnt.sort + has\_nil

and for another you want

has\_nil + doesn’t.sort

hope that helps. Excuse the incomplete code 🙂

---

<div class="post-metadata">

**Author:** ![thechak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/aeb1de/32.png) [@thechak](https://www.ruby-forum.com/u/thechak)\
**Post date:** [August 10, 2007, 11:50pm UTC](https://www.ruby-forum.com/t/using-the-spaceship-operator-to-compare-nil/111693/4 "2007-08-10T23:50:41Z")

</div>

On Aug 9, 5:39 pm, “Gregory B.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> and for another you want
> 
> has\_nil + doesn’t.sort
> 
> hope that helps. Excuse the incomplete code 🙂

Thanks, Gregory. This is what I ended up with (works well) ~

def assert\_ordered\_by(attribute, collection, direction)  
collection = assigns[“#{collection.to\_s}”]  
return true if collection.length \< 2  
has\_nil, has\_no\_nil = collection.partition { |r|  
r.send(attribute).nil? }  
has\_no\_nil = has\_no\_nil.sort\_by(&:“#{attribute}”)  
expected = has\_nil + has\_no\_nil  
expected.reverse! if direction.include?(“\>”)  
assert\_equal expected.map(&:“#{attribute}”),  
collection.map(&:“#{attribute}”)  
end
