[LRUG] Comparable Null Objects
Duncan Stuart
dgmstuart at gmail.com
Wed Jul 15 07:58:45 PDT 2015
Thanks Frederick and Rob
Defining to_date doesn't suffice: the <=> method on Date doesn't try and
coerce the argument into a date, which is why Date.today > Time.now fails,
even though Time responds to to_date.
If I were to define a coercion method, I think it would have to be on Date,
which feels wrong.
On 15 July 2015 at 13:21, Rob Isenberg <robisenberg at me.com> wrote:
> 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
>
>
> _______________________________________________
> 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/3aa9ff03/attachment-0003.html>
More information about the Chat
mailing list