<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<span id="mailbox-conversation"><div><br></div>
<div>| Some events don't have an expected date, so like a good little OO programmer i've created a Null object:</div>
<div><br></div>
<div>Yay! Good OO programmer.</div>
<div><br></div>
<div>| but when it comes to sorting the list</div>
<div><br></div>
<div>wait, wat? Less good OO programmer.</div>
<div><br></div>
<div>I can see three things going on here, pretty much simultaneously.</div>
<div><br></div>
<div>1) You want to sort a list of different types of things. Like when you try to sort a list of Silverback Gorillas and instances of the number 37 it’s hard because it doesn’t really make sense.</div>
<div><br></div>
<div>2) You don’t have a list. You have an Array object. Is this the best place to send the ‘sort’ message to? Should it own the behaviour of sorting these particular disparate types of things?</div>
<div><br></div>
<div>3) You switched from clean OO thinking (we need an object to encapsulate this state) to imperative thinking (we have a list and we need to sort it).</div>
<div id="orc-email-signature" style="display:block;"><div class="mailbox_signature">
<div class="mailbox_signature" id="mb-reply"><br></div>
<div class="mailbox_signature" id="mb-reply">I blame Ruby for all of this. It makes you think you’re doing OO programming but throws in many non-OO ideas to trip you up.</div>
<div class="mailbox_signature" id="mb-reply"><br></div>
<div class="mailbox_signature" id="mb-reply">It’s not clear that an OO approach is the best approach here, but if you want to follow it try to think less about objects and more about the messages between objects. E.g., instead of ‘I need to sort a list’ think ‘I need to send a message somewhere telling it to do something (in this case to… what? To sort some objects? But why do you care?)’.</div>
<div class="mailbox_signature" id="mb-reply"><br></div>
<div class="mailbox_signature" id="mb-reply">Hope this helps or at least makes you think or at the very least persuades you to rage quit programming and go and live in a forest,</div>
<div class="mailbox_signature" id="mb-reply">John</div>
<div class="mailbox_signature" id="mb-reply"><br></div>
</div></div>
<br><span id="orc-full-body-initial-text" style="display:inline;">On Wednesday, Jul 15, 2015 at 1:03 pm, Duncan Stuart <<a href="mailto:dgmstuart@gmail.com" target="_blank">dgmstuart@gmail.com</a>>, wrote:<br></span></span><span class="none"><blockquote class="gmail_quote"><div><div dir="ltr">Hi LRUG - hopefully an interesting little problem:<br><br>I have an Event class which has an "expected_date" attribute.<br>Some events don't have an expected date, so like a good little OO programmer i've created a Null object:<br><br><div>class NoExpectedDate</div>
<div>  def to_s(format=:default)</div>
<div>    "Unknown"</div>
<div>  end</div>
<div>end</div>
<div><br></div>
<div>This works great for printing the values, but when it comes to sorting the list I of course get:<br><br><br><br><br><br><br><br><br><br><br>   ArgumentError: comparison of Date with NoExpectedDate failed <br><br>If I include Comparable and define <=> then one comparison works, but the other doesn't :<br><br><div>class NoExpectedDate</div>
<div>  include Comparable</div>
<div>  def to_s(format=:default)</div>
<div>    "Unknown"</div>
<div>  end</div>
<div>  def <=>(other_date)</div>
<div>    1 # Treat it as after every other date</div>
<div>  end</div>
<div>end</div>
</div>
<div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><p class=""><span class="">$ </span><span class="">NoExpectedDate</span><span class="">.new > </span><span class="">Date</span><span class="">.today<br></span><span class="">=> </span><span class="">true</span></p>
<br><br><p class=""><span class="">$ </span><span class="">Date</span><span class="">.today > </span><span class="">NoExpectedDate</span><span class="">.new<br></span>ArgumentError: comparison of Date with NoExpectedDate failed<br><br>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.<br><br>Can I get NoExpectedDate to pretend to be a Date (like SimpleDelegator lies about it's class)? Is that evil?<br><br>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:<br><br></p>
<p class="">def sort_by_expected_date sort do |a, b| </p>
<p class="">    if b.class = NoExpectedDate </p>
<p class="">      1</p>
<p class="">    else</p>
<p class="">      a <=> b</p>
<p class="">    end</p>
<p class="">  end</p>
<p class="">end</p>
<p class=""><br></p>
</div>
</div></div></blockquote></span>
</body></html>