我需要比较潜在的nil
个对象。例如,
Foo.new(Date.new) < Foo.new(nil)
# => true
Foo.new(nil) < Foo.new(Date.new)
# => true
class Foo
attr_accessor :time
def initialize(time)
@time = time
end
def <=>(other)
# I don't know what to do here.
end
end
是否有解决此类问题的模式?
答案 0 :(得分:3)
您可以定义Foo#to_f
方法:
@time
,则返回@time.to_f
@time
为零,则返回负无穷大这样,Foo.new(nil)
小于任何其他Foo
。
require 'date'
class Foo
attr_accessor :time
include Comparable
def initialize(time)
@time = time && time.to_time # time can be nil, a Date or a Time
end
def to_f
@time ? @time.to_f : -Float::INFINITY
end
def <=>(other)
to_f <=> other.to_f
end
def to_s
@time ? @time.strftime('%Y-%m-%d') : 'nil'
end
alias inspect to_s
end
p Foo.new(Date.new) < Foo.new(nil)
# false
p Foo.new(nil) < Foo.new(Date.new)
# true
p [Foo.new(Date.today), Foo.new(nil), Foo.new(Date.new(2015, 3, 1)), Foo.new(Date.new(2018, 5, 14)), Foo.new(Time.now + 3600)].sort
# [nil, 2015-03-01, 2017-06-24, 2017-06-25, 2018-05-14]
require 'date'
class NilTime
def to_f
- Float::INFINITY
end
def strftime(*)
'nil'
end
end
class Foo
attr_accessor :time
include Comparable
def initialize(time = nil)
@time = if time.respond_to?(:to_time)
time.to_time
else
NilTime.new
end
end
def to_f
@time.to_f
end
def <=>(other)
to_f <=> other.to_f
end
def to_s
@time.strftime('%Y-%m-%d')
end
alias inspect to_s
end
答案 1 :(得分:1)
另一种方式
nil.to_i为0
nil_obj.to_i < date_obj.to_i
Foo.new(nil.to_i) < Foo.new(Date.to_i) # true