I have this class:
class SimpleDate
include Comparable
VALS = [:year, :month, :day]
attr_accessor *VALS
def initialize(year, month, day)
@year = year
@month = month
@day = day
end
#ideas on making this much shorter are welcome
def <=>(other)
VALS.each do |key|
v1 = self.send(key)
v2 = other.send(key)
result = (v1 <=> v2)
if result != 0
return result
end
end
0
end
end
that represents a date that might have any of the three parts not
existant. For some reason date1 == date2 returns nil when done like
this:
class SimpleDateTest < Test::Unit::TestCase
def test_comparison_with_nils
date1 = SimpleDate.new(1,nil,nil)
date2 = SimpleDate.new(1,nil,nil)
assert_not_equal date1.object_id, date2.object_id
assert date1 == date2
end
end
The code shouldn’t even work because nil doesn’t implement <=>. What
the hell is comparable doing behind my back?
I thought date1 == date2 was the same as (date1 <=> date2> == 0 but
apparently not.
Pedro.
Pedro Côrte-Real wrote:
end
0
end
end
How about something like this (untested):
def <=>(other)
VALS.map{ |key| self.send(key) } <=> VALS.map{ |key| other.send(key)
}
end
Pedro Côrte-Real wrote:
@month = month
if result != 0
return result
end
end
0
end
end
shorter
SimpleDate = Struct.new :year, :month, :day do
include Comparable
def <=> (other)
self.class.members.each do |field|
result = send(field) <=> other.send(field)
return result unless result == 0
end
0
end
end
assert date1 == date2
end
end
The code shouldn’t even work because nil doesn’t implement <=>. What
the hell is comparable doing behind my back?
I thought date1 == date2 was the same as (date1 <=> date2> == 0 but
apparently not.
No, it’s differently implemented.
Kind regards
robert
On 7/31/06, Robert K. [email protected] wrote:
I thought date1 == date2 was the same as (date1 <=> date2> == 0 but
apparently not.
No, it’s differently implemented.
How then? According to the docs if you implement <=> and include
Comparable you get ==. But my second assertion is failing when it
should be blowing up when trying to do nil <=> nil.
Pedro.
“P” == =?ISO-8859-1?Q?Pedro C=F4rte-Real?= writes:
P> The code shouldn’t even work because nil doesn’t implement <=>. What
P> the hell is comparable doing behind my back?
Try it with 1.9
Guy Decoux
On 7/31/06, Robin S. [email protected] wrote:
How about something like this (untested):
def <=>(other)
VALS.map{ |key| self.send(key) } <=> VALS.map{ |key| other.send(key) }
end
Good idea. I’m gonna try it.
Pedro.
On 7/31/06, Pedro Côrte-Real [email protected] wrote:
On 7/31/06, Robin S. [email protected] wrote:
How about something like this (untested):
def <=>(other)
VALS.map{ |key| self.send(key) } <=> VALS.map{ |key| other.send(key) }
end
I tried it like this:
def <=>(other)
p ‘At the start’
result = VALS.map{|key| self.send(key)} <=> VALS.map{|key|
other.send(key)}
p ‘At the end’
result
end
And the strange thing is that ‘At the end’ isn’t printed but ‘At the
start’ is. How can this be?
Pedro.
On 7/31/06, ts [email protected] wrote:
“P” == =?ISO-8859-1?Q?Pedro C=F4rte-Real?= writes:
P> The code shouldn’t even work because nil doesn’t implement <=>. What
P> the hell is comparable doing behind my back?
Try it with 1.9
I don’t have one around. Has this changed? I’d like to make this work
now. I thought implementing <=> and including Comparable gave me ==
but something else seems to be going on.
Pedro.
On 7/31/06, ts [email protected] wrote:
moulon%
moulon% ruby -v -e ‘p NameError.ancestors’
ruby 1.9.0 (2006-07-14) [i686-linux]
[NameError, ScriptError, Exception, Object, Kernel, BasicObject]
moulon%
Ah, right, the exception is being caught. Here’s a working version then:
def <=>(other)
VALS.map{|key| self.send(key)||0} <=> VALS.map{|key|
other.send(key)||0}
end
Much cleaner than my first and this time it actually works.
Pedro.
“P” == =?ISO-8859-1?Q?Pedro C=F4rte-Real?= writes:
P> And the strange thing is that ‘At the end’ isn’t printed but ‘At the
P> start’ is. How can this be?
Comparable#== catch StandardError
moulon% /usr/bin/ruby -v -e ‘p NameError.ancestors’
ruby 1.8.4 (2005-12-24) [i486-linux]
[NameError, StandardError, Exception, Object, Kernel]
moulon%
moulon% ruby -v -e ‘p NameError.ancestors’
ruby 1.9.0 (2006-07-14) [i686-linux]
[NameError, ScriptError, Exception, Object, Kernel, BasicObject]
moulon%
Guy Decoux
Pedro Côrte-Real wrote:
On 7/31/06, Robert K. [email protected] wrote:
I thought date1 == date2 was the same as (date1 <=> date2> == 0 but
apparently not.
No, it’s differently implemented.
How then? According to the docs if you implement <=> and include
Comparable you get ==. But my second assertion is failing when it
should be blowing up when trying to do nil <=> nil.
You get == but if you implement it yourself your version will shadow the
one from Comparable:
class Foo
def <=>(o) 0 end
include Comparable
end
=> Foo
Foo.instance_method :==
=> #<UnboundMethod: Foo(Comparable)#==>
Now we add it to Foo:
class Foo
def ==(o) false end
end
=> nil
Foo.instance_method :==
=> #<UnboundMethod: Foo#==>
Foo.ancestors
=> [Foo, Comparable, Object, Kernel]
Kind regards
robert