From: Brian Candler Date: 2004-09-17T20:52:41+09:00 Subject: Re: Automatic class conversion / function overloading On Fri, Sep 17, 2004 at 07:04:53PM +0900, Tore Halvorsen wrote: > In C++ it's possible to have function overloading... ie > > void foo(int a) and void foo(rational a) > > Do I have to resort to > > def foo(a) > case a > when Fixnum ... > when Rational ... > end > end > > or is there any other way to do this? Essentially it's what you've written. However, you'll find that in more cases than you expect you don't actually do it. As long as the objects passed in respond to the same methods, you can just invoke them without caring what the class is; there is no need for them to be inherited from some common superclass as would be the case in C++. As an example: def foo(logger) logger << "hello world\n" end This works whether logger is a File, a String, or an Array (even though their common ancestors are Object and Kernel, which don't have a << operator). There's no need to write def foo(logger) case logger when File ... when String ... when Array ... end end It doesn't work if logger is a Fixnum, but then, it doesn't make sense to append a log string to a Fixnum anyway. Have a look through Ruby's built-in library. For example, in 'expect.rb' you'll see several cases where a function can be called either with a hash or a string as an argument, and it behaves differently in those cases. Actually, you're often more interested in what methods an object responds to, rather than its class. In the logger example you're more likely to have logger.flush if logger.respond_to?(:flush) rather than case logger when File, IO logger.flush end You're basically assuming a convention that an IO-like object has methods "<<" to append and "flush" to flush (if it can be flushed). Such conventions seem to work well in practice. If you came across an object which didn't, you could add a "<<" method to that object or to its class to do what you want, or make a wrapper object which normalises the method call interface. Exception handling is another way to avoid explicit tests for class: begin logger.flush rescue NoMethodError end Regards, Brian.