NilClass and Comparable

R

RubyTalk

nil==0
=> false
class NilClass
include Comparable
def <=>(other)
0
end
end => nil
[1,nil,2].sort
ArgumentError: comparison of Fixnum with nil failed
from (irb):11:in `sort'
from (irb):11false
=> nilfalse
=> niltrue
=> nil



What I am missing here?
 
A

Adam Gardner

nil==0 => false
class NilClass
include Comparable
def <=>(other)
0
end
end => nil
[1,nil,2].sort
ArgumentError: comparison of Fixnum with nil failed
from (irb):11:in `sort'
from (irb):11false
=> nilfalse
=> niltrue
=> nil



What I am missing here?

Probably this:

irb(main):003:0> class NilClass
irb(main):004:1> def <=>(other)
irb(main):005:2> 0
irb(main):006:2> end
irb(main):007:1> end
=> nil
irb(main):008:0> nil <=> 1
=> 0
irb(main):009:0> 1 <=> nil
=> nil
irb(main):010:0>
 
R

RubyTalk

Yes! Thats exactly what I was missing. Why would someone write <=3D> for n=
il?

nil=3D=3D0 =3D> false
class NilClass
include Comparable
def <=3D>(other)
=A00
end
end =3D> nil
[1,nil,2].sort
ArgumentError: comparison of Fixnum with nil failed
=A0 from (irb):11:in `sort'
=A0 from (irb):11
p nil > 2
false
=3D> nil
p nil > -1
false
=3D> nil
p nil =3D=3D 0
true
=3D> nil



What I am missing here?

Probably this:

irb(main):003:0> class NilClass
irb(main):004:1> def <=3D>(other)
irb(main):005:2> 0
irb(main):006:2> end
irb(main):007:1> end
=3D> nil
irb(main):008:0> nil <=3D> 1
=3D> 0
irb(main):009:0> 1 <=3D> nil
=3D> nil
irb(main):010:0>
 
R

Robert Klemme

Yes! Thats exactly what I was missing. Why would someone write <=> for nil?

There is probably no good reason because nothing doesn't compare well to
anything - and so the method is not defined. :)

Kind regards

robert
 
B

Brian Candler

Robert said:
There is probably no good reason because nothing doesn't compare well to
anything - and so the method is not defined. :)

It can be useful to have an ordering defined for mixed collections. For
example, CouchDB defines a full ordering across null, numbers, strings,
arrays and objects (hashes):
http://wiki.apache.org/couchdb/View_collation

In Ruby, the solution depends on what exactly you're trying to do. Maybe
sort_by with a default value is good enough for what you need.

arr.sort_by { |e| e || -1 }

You can also use arr.sort { |a,b| ... } and then the block defines the
'<=>' logic for comparing two objects.

Note that it would be dangerous to define nil <=> any and any <=> nil to
be 0, because that would mean (any number) == nil == (any other number).
For example,

[2, nil, 1]

could be treated as an already-sorted array!

Instead, you might want to define nil <=> x as -1 and x <=> nil as +1
(where x is any non-nil value). You can do that in your sort block.

Regards,

Brian.

P.S. Also be aware that ruby's sort is implemented using quicksort
(IIRC), which is not stable for equal keys.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top