[LRUG] Comparable Null Objects

Duncan Stuart dgmstuart at gmail.com
Thu Jul 16 05:03:00 PDT 2015


Many thanks Tom - this makes a lot of sense.

One thing you could maybe help me understand:
I have this bit of dogma in my head that type checking is evil - including
nil-checking. I haven't deeply understood why this is, but thinking about
it but my best guess is that it's an application of DIP (?) “Depend upon
Abstractions. Do not depend upon concretions.”

I get that most 'rules' have scenarios where they doesn't apply, and that
the key is to understand the underlying principles behind that rule - I'm
just not sure what they are.

In this case is it a trade-off, or does it just not apply?
Because this class is genuinely concerned with Dates (or NoExpectedDates?)
and no other type?
Because ordering on Dates in Ruby requires actual Dates and not Date-like
things, forcing us into an undesirable implementation?

Would something like `when Date, Numeric` be preferable to `when
NoExpectedDate`
be preferable at all?

Cheers

Duncan

On 16 July 2015 at 10:27, <tom at codon.com> wrote:

> On 15 Jul 2015, at 22:44, Duncan Stuart <dgmstuart at gmail.com> wrote:
> > Do you think I'm applying the idea incorrectly or inappropriately?
>
> FWIW I do think you’re misapplying the idea, for the simple reason that it
> doesn’t really help here. The null object pattern is helpful when there’s
> some protocol that can sensibly be replicated by the null object; your `def
> to_s; 'Unknown'; end` is a good example. But there’s no easy way for a null
> object to conform to the expectations of Date#<=>, so it’s not going to
> make things better.
>
> My advice would be to avoid trickery entirely and take a different piece
> of advice from Sandi’s talk: extract a role. Make a new kind of object
> whose sole responsibility is the (not entirely trivial) logic of ordering
> things by date when some of them may not have dates.
>
> There are a few ways of doing this, but one example might be to have a
> DateRank class:
>
> DateRank = Struct.new(:maybe_date) do
>   def <=>(other)
>     if maybe_date.nil?
>       1
>     elsif other.maybe_date.nil?
>       -1
>     else
>       maybe_date <=> other.maybe_date
>     end
>   end
> end
>
> (Substitute `case maybe_date … when NoExpectedDate` for `if nil?` if you
> choose to use null objects for other reasons — the two ideas are
> orthogonal.)
>
> And then you can do `events.sort_by(&DateRank.method(:new))` or whatever.
>
> I talk about this idea a bit in
> http://codon.com/a-lever-for-the-mind#poker if you’re interested.
>
> Cheers,
> -Tom
> _______________________________________________
> 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/20150716/597d718f/attachment-0003.html>


More information about the Chat mailing list