[LRUG] Comparable Null Objects

Mark Wilkinson mhw+lrug at dangerous-techniques.com
Wed Jul 15 08:27:42 PDT 2015


Hmm; previous attempt to send this seems to have failed. Think it might be
my plussed subscription address.

On Wed, Jul 15, 2015 at 1:17 PM, Frederick Cheung <
frederick.cheung at gmail.com> wrote:

>
>
>
> On 15 July 2015 at 13:03:21, Duncan Stuart (dgmstuart at gmail.com) wrote:
>
> $ 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 think this is what coercion is for (e.g.
> http://www.mutuallyhuman.com/blog/2011/01/25/class-coercion-in-ruby/ )
>

Yep, #coerce is what you're looking for but it's not very clearly
documented. The documentation for Date#<=> doesn't admit that it calls
coerce, but that's what it does if it can't deal with the types of the
arguments.

The implementation of #coerce is a bit tricky: the method is passed the
other operand of whichever binary operator has been invoked, so calling
'Date.today > NoExpectedDate.new' will eventually result in
NoExpectedDate#coerce being passed the value of Date.today. Here's an
implementation that works:

require 'date'

class NoExpectedDate
  include Comparable

  def to_s(format=:default)
    "Unknown"
  end

  def <=>(other_date)
    1
  end

  def coerce(other)
    case other
    when Date
      return other, Float::INFINITY
    else
      nil
    end
  end
end

puts NoExpectedDate.new > Date.today # true
puts Date.today > NoExpectedDate.new # false

l = [
  Date.new(1789, 7, 14),
  Date.new(1215, 6, 15),
  NoExpectedDate.new,
  Date.new(1066, 10, 14),
]

puts l.sort.join(', ') # 1066-10-14, 1215-06-15, 1789-07-14, Unknown


-Mark.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lrug.org/pipermail/chat-lrug.org/attachments/20150715/314bf627/attachment-0003.html>


More information about the Chat mailing list