[LRUG] Comparable Null Objects

Rob Isenberg robisenberg at me.com
Wed Jul 15 05:21:55 PDT 2015


Hi Duncan, if you want your class to be comparable with other built-in objects, I think you need to implement any #to_* methods that make sense.

I think you need to write a #to_date method which with then automatically be coerced when the comparison is done starting with a Date object. 

Sent from my iPhone

> On 15 Jul 2015, at 13:04, Duncan Stuart <dgmstuart at gmail.com> wrote:
> 
> Sorry that last code snippet should be:
> def sort_by_expected_date
>   sort do |a, b| 
>     if b.class = NoExpectedDate 
>       1
>     else
>       a <=> b
>     end
>   end
> end
> 
> 
>> On 15 July 2015 at 13:03, Duncan Stuart <dgmstuart at gmail.com> wrote:
>> Hi LRUG - hopefully an interesting little problem:
>> 
>> I have an Event class which has an "expected_date" attribute.
>> Some events don't have an expected date, so like a good little OO programmer i've created a Null object:
>> 
>> class NoExpectedDate
>>   def to_s(format=:default)
>>     "Unknown"
>>   end
>> end
>> 
>> This works great for printing the values, but when it comes to sorting the list I of course get:
>>    ArgumentError: comparison of Date with NoExpectedDate failed 
>> 
>> If I include Comparable and define <=> then one comparison works, but the other doesn't :
>> 
>> class NoExpectedDate
>>   include Comparable
>>   def to_s(format=:default)
>>     "Unknown"
>>   end
>>   def <=>(other_date)
>>     1 # Treat it as after every other date
>>   end
>> end
>> $ NoExpectedDate.new > Date.today
>> => true
>> 
>> $ Date.today > NoExpectedDate.new
>> ArgumentError: comparison of Date with NoExpectedDate failed
>> 
>> I think this is because Date's <=> method expects it's argument to be a Date object or a number ("a numeric value as an astronomical Julian day number"). I've tried defining to_i and to_r on NoExpectedDate, but no dice.
>> 
>> Can I get NoExpectedDate to pretend to be a Date (like SimpleDelegator lies about it's class)? Is that evil?
>> 
>> I suppose I could always just define a method on Event to do this particular sort, but that seems nasty for all sorts of reasons:
>> 
>> 
>> def sort_by_expected_date sort do |a, b| 
>> 
>>     if b.class = NoExpectedDate 
>> 
>>       1
>> 
>>     else
>> 
>>       a <=> b
>> 
>>     end
>> 
>>   end
>> 
>> end
>> 
> 
> _______________________________________________
> Chat mailing list
> Chat at lists.lrug.org
> Archives: http://lists.lrug.org/pipermail/chat-lrug.org
> Manage your subscription: http://lists.lrug.org/options.cgi/chat-lrug.org
> List info: http://lists.lrug.org/listinfo.cgi/chat-lrug.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lrug.org/pipermail/chat-lrug.org/attachments/20150715/a4f9bdf0/attachment-0003.html>


More information about the Chat mailing list