Quoting dblack / wobblini.net, on Sat, May 20, 2006 at 09:20:20AM +0900:
> Do be careful, though.  Remember that the changes you make to Object
> and NilClass will be in effect for all the library code that you
> include in your application, including the standard library, so if
> anyone else is relying on the fact that some objects respond to "each"
> and others don't, or that nil is dimensionless, something could go
> wrong.

Whats the current wisdom on how to do this more nicely?

I've got a library that added #to_time to the Date builtin... and its
conflicting with another much more commonly used library, that has done
the same thing, but give time in local TZ, not UTC. Oops...


Easy way, is to move my code out into a utility method

module Util
  def to_time(v)
    case v
    when Time
      v
    when Date
      ... cvt v to a Time ..
    else
     ... ?
    end
  end
end

but switches on class type are usally a bad thing... in OO code
generally, and in ruby in particular we are supposed to duck-type, and
its a real posibility that also DateTime, and perhaps even other date or
time classes might wander into my code. I'd really like not have this
kind of switch statement.

What to do?

I could change my method name from Date#to_time, to
Date#vpim_to_time_utc, basically namespacing my extension, and adding
one to Time as well.

I was also considering having some kind of hash:

module Util
  @@cvt_to_time_utc = {
    Time => lambda{|t| t },
    Date => lambda(|d| Time.utc(d.year, d.mon, d.day)
    }
  def self.cvt_to_time_utc(v)
    @@cvt_to_time_utc[v.class].call(v)
  end
end

Then 3rd party classes could register some handlers to convert to Time
in UTC, and I wouldn't have to modify my case statements.

But... what if they have

  class MyTime < Time
  end

That won't work... so I could maybe be more clever, search their
ancestry looking for something that is in my hash.... This is starting
to be a bit of work, and unfotunately similar to what ruby does for
method dispatch...

Maybe just using name mangling, using my library prefix, is the way to
go!

Thoughts?


Cheers,
Sam