Hi -- On Mon, 28 May 2007, Erwin Abbott wrote: > On 5/27/07, dblack / wobblini.net <dblack / wobblini.net> wrote: >>> I think it works pretty well, but I'd like to know what you prefer >>> instead. I realize distinguishing objects by class is not encouraged, >>> but I find myself needing it often, for better or worse. >> >> But you're running aground on exactly why it isn't encouraged: namely, >> it doesn't give you definitive information about the object's behavior >> or interface. > > Say you have some method that accepts various objects that represent a > time. It's job is to return true if the given time is more than a week > old. We have DateTime, Time, Date, and probably some more I don't know > about. We can test that these objects have a comparison operator, and > not pay attention to their class, but that doesn't help me because > Date.new < Time.now doesn't work. In fact, Date's <=> checks if it was > passed an Integer or a Date object, because knowing the object's class > is necesarry to know how to compare them. > > I don't see any other way to write that method, am I missing > something? It seems the most definitive information about any objects > behavior is its source code, next to that we can ask what class it is > and look up the documentation. I agree distinguishing objects by class > has its problems, like Date#<=> doesn't work with anything but Dates > and Integers (when maybe it should be testing respond_to? :ajd when it > isn't given an Integer), but is there a better alternative? > >> Are you sure a mixin wouldn't make more sense? > > Instead of using a proxy? It's a trade-off at this point between > getting case to work and having to write code that can't use intstance > variable names like @id or @name because the original object might > already be using them, or having to alias an existing #name as > #old_name and making sure my #name doesn't break any code in that > class. I might still break something with a proxy class answering > #name, but it won't break the underlying object when it calls name on > itself. I think at this point I'll accept that case statements won't > work, but I'm going to try a few other things before giving up. I was thinking of something like (semi-tested only): module DateComp def <(other) Time.parse(strftime("%m/%d/%y")) < other end end d = Date.new.extend(DateComp) your_method(d) That way, you can use duck typing in the method itself, which means that you don't have to change the method if you want to provide it with other objects; you just have to prepare things on the calling end. You might have to have a more complex mixin for your proxy case, but anyway, that's the kind of thing I was thinking about. David -- Q. What is THE Ruby book for Rails developers? A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black) (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf) Q. Where can I get Ruby/Rails on-site training, consulting, coaching? A. Ruby Power and Light, LLC (http://www.rubypal.com)