# Nil Comparable

**URL:** <https://www.ruby-forum.com/t/nil-comparable/88798>\
**Category:** Ruby\
**Created:** [March 14, 2007, 2:48pm UTC](https://www.ruby-forum.com/t/nil-comparable/88798 "2007-03-14T14:48:00Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 14, 2007, 2:48pm UTC](https://www.ruby-forum.com/t/nil-comparable/88798/1 "2007-03-14T14:48:00Z")

</div>

Does anyone see anything problematic about this?

class NilClass

```
include Comparable

def <=>(x)
  x.nil? ? 0 : -1
end

def succ; nil; end

```

end

It seems benign enough, and can be used to represent “always before”.  
For instance, in Rake there is a class called EarlyTime: “EarlyTime is  
a fake timestamp that occurs before any other time value.” And that’s  
all that it does. If NilClass were comparable per the above then  
EarlyTime would not be needed.

T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 14, 2007, 3:00pm UTC](https://www.ruby-forum.com/t/nil-comparable/88798/2 "2007-03-14T15:00:02Z")

</div>

On Wed, 14 Mar 2007, Trans wrote:

> def succ; nil; end
> 
> end
> 
> It seems benign enough, and can be used to represent “always before”.  
> For instance, in Rake there is a class called EarlyTime: “EarlyTime is  
> a fake timestamp that occurs before any other time value.” And that’s  
> all that it does. If NilClass were comparable per the above then  
> EarlyTime would not be needed.

it could mask errors like

[42, nil].sort

depending on the order of comparison it may or may not work since we  
might get

42.send ‘\<=\>’, nil

or

nil.send ‘\<=\>’, 42

so it’s a bit different in that it’s weakly typed where as the EarlyTime  
class  
is strongly typed - it’ll only compare with other times

still - it **is** handy. if you search the archives i’ve suggeted that  
-Infinity and Infinity have these kinds of properties wrst numerics a  
few  
times.

cheers.

-a

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 14, 2007, 4:13pm UTC](https://www.ruby-forum.com/t/nil-comparable/88798/3 "2007-03-14T16:13:11Z")

</div>

removed\_email\_address@domain.invalid wrote:

> > end
> 
> cheers.
> 
> -a  
> The Facets library includes all of the above-mentioned features of  
> usefulness.  
> [http://facets.rubyforge.org/](http://facets.rubyforge.org/)  
> There are a lot of other extensions to the Ruby core in it, and they can  
> mostly be included in small chunks, so they are easy to use.  
> I hope this helps!

Thus spake the monkey

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 14, 2007, 9:58pm UTC](https://www.ruby-forum.com/t/nil-comparable/88798/4 "2007-03-14T21:58:18Z")

</div>

On Mar 14, 11:12 am, Ronnie [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > ```
> > > x.nil? ? 0 : -1
> > > 
> > > ```
> > > 
> > > EarlyTime would not be needed.  
> > > or
> 
> > cheers.
> 
> > -a
> 
> The Facets library includes all of the above-mentioned features of  
> usefulness.[http://facets.rubyforge.org/](http://facets.rubyforge.org/)  
> There are a lot of other extensions to the Ruby core in it, and they can  
> mostly be included in small chunks, so they are easy to use.  
> I hope this helps!

He he… The code I listed actually came right from Facets 🙂

Much thanks though!

T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 14, 2007, 11:27pm UTC](https://www.ruby-forum.com/t/nil-comparable/88798/5 "2007-03-14T23:27:32Z")

</div>

On 3/14/07, Ronnie [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > ```
> > > x.nil? ? 0 : -1
> > > 
> > > ```
> > > 
> > > EarlyTime would not be needed.  
> > > or
> > 
> > cheers.
> > 
> > -a  
> > The Facets library includes all of the above-mentioned features of  
> > usefulness.  
> > [http://facets.rubyforge.org/](http://facets.rubyforge.org/)  
> > There are a lot of other extensions to the Ruby core in it, and they can  
> > mostly be included in small chunks, so they are easy to use.  
> > I hope this helps!  
> > Well I guess Tom knows about Facets Ronnie 🙂  
> > [http://rubyforge.org/projects/facets/](http://rubyforge.org/projects/facets/)  
> > as you might know this link :).
> 
> Thus spake the monkey

It must be quite rewarding though to get pointed to your own project I  
would love that 😉

Cheers  
Robert

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 15, 2007, 1:41am UTC](https://www.ruby-forum.com/t/nil-comparable/88798/6 "2007-03-15T01:41:45Z")

</div>

On Mar 14, 6:26 pm, “Robert D.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> It must be quite rewarding though to get pointed to your own project I  
> would love that 😉

Yes, and rather surprising at the same time. I’m not sure what to make  
of it actually.

T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 15, 2007, 8:42am UTC](https://www.ruby-forum.com/t/nil-comparable/88798/7 "2007-03-15T08:42:25Z")

</div>

On Mar 14, 9:59 am, removed\_email\_address@domain.invalid wrote:

> it could mask errors like
> 
> so it’s a bit different in that it’s weakly typed where as the EarlyTime class  
> is strongly typed - it’ll only compare with other times
> 
> still - it **is** handy. if you search the archives i’ve suggeted that  
> -Infinity and Infinity have these kinds of properties wrst numerics a few  
> times.

Infinity and \_Infinity would be a better fit, I agree. But is it  
possible for them to always be lesser or greater no matter if they are  
the receiver or argument of a comparison? That’s doesn’t seem to fit  
well with OOP design. And it’s not very practical to add this  
constraint to ever definition of \<=\> in every class. Although maybe  
\<=\> could be defined in Kernel with the constraints and super could be  
called to get that functionality. Eg.

module Kernel  
def \<=\>(other)  
return 1 if -Infinity == other  
return -1 if Infinity == other  
0  
end  
end

then

class Integer  
def \<=\>(other)  
if (c = super) != 0 then return c  
…

T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 15, 2007, 7:04am UTC](https://www.ruby-forum.com/t/nil-comparable/88798/8 "2007-03-15T07:04:15Z")

</div>

On 3/15/07, Trans [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> T.

As a matter of fact it is remarkable how you use the list as a tool to  
improve the code and ideas of facets …  
Poor Ronnie got caught by your humble attitude, but it was funny - in  
a nice way.

Personally for what it is worth:  
I avoid his kind of trickery with core classes when I think my code  
might become an API and I use it freely in applications (e.g. DSLs).  
Now I am really not studied enough to tell you: DONT, but that would  
be my advice if I were forced to give one.  
This aligns pretty well with recent posts and the point of view from  
learned gurus like David or Ara, I still might fail to see the whole  
picture of course.

Cheers  
Robert

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 15, 2007, 10:16am UTC](https://www.ruby-forum.com/t/nil-comparable/88798/9 "2007-03-15T10:16:41Z")

</div>

On 3/15/07, Trans [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > def \<=\>(x)  
> > > all that it does. If NilClass were comparable per the above then  
> > > or  
> > > Infinity and \_Infinity would be a better fit, I agree. But is it  
> > > return -1 if Infinity == other  
> > > 0  
> > > end  
> > > end  
> > > Will that be good enough? People will often write their #\<=\> in classes.  
> > > Better than nothing of course.
> 
> then
> 
> class Integer  
> def \<=\>(other)  
> if (c = super) != 0 then return c  
> …
> 
> T.

I really hate not having more time and/or knowledge.  
I had talked about this twice on the list but the second time (the  
peak of the iceberg) I never found the time to elaborate.

I am very unhappy with the \<=\> paradigm for Comparable I really prefer  
the Less Pattern (no idea why it has that name, maybe I recall  
incorrectly) should be LessEqual.  
Tom I guess you are familiar with it - I have posted this before, sorry

module Comparable

# relies on #\<= only

def \< other; self \<= other && ! other \<= self end  
def \> other; other \<= self && ! self \<= other end  
def \>= other; other \<= self end  
def == other; other \<= self && self \<= other end  
def != other; ! self == other; end  
end

At first sight there are two major advantages, we can use it for half  
orders where neither x \<= y nor y \<= x hold !  
And more important in your context the module Comparable enforces the  
symmetry of the #\<= method, it does not show up later when you are  
sorting.

Performance of course is a catastrophe ☹

Cheers  
Robert
