From: "Benjamin J. Tilly" Date: 2001-05-08T05:24:45+09:00 Subject: [ruby-talk:14808] RE: Polymorphic methods >===== Original Message From "J J" ===== >In C++ you can have polymorphic methods such as > >doIt( String s ) { >... >} > >doIt( Integer i ) { >... >} > >Is there a way to duplicate this behavior without resorting to: > >def doIt( object ) > if object.type == String > ... > elsif object.type == Numeric > ... > end >end Yes. Two solutions. 1. Create a hash whose keys are the types of object you want, and whose values are the subroutines you want. (You can create anonymous subroutines with the "proc" method in the kernel.) Then you can do this: def doIt (object) $action[object.type][object] end Feel free to add existence checks and a default case. Also you may want to add logic to follow the inheritance hierarchy in case someone tries to subclass a type you know about. This is called "dispatching on a hash lookup". 2. Create a method in each class that you want and then call the method. This is how Ruby already converts things to integers, floats, strings. If you do this be sure to give things a good name. Like "to_month". Now you get: def doIt (object) object.to_month end This is called "dispatching on a method lookup". For reasons that you can see, there is little need to have a function to wrap the dispatch. What it is good for is trapping the case where you are missing the method. In that case you can either have the method as above, or you can put a default method in class Object. I have used both methods in multiple languages. There are some tradeoffs. >I'm thinking of instances (for example) where you can create an object from >several different objects passed to the constructor. E.g. > >m = Month.new(12) >m = Month.new('December') >m = Month.new(anotherMonth) > >thus, Month.initialize has to have a case or if statement. This is the kind of thing where you probably want to work right if someone subclasses a class. I would therefore be likely to choose dispatching on a method lookup so I didn't have to follow the inheritance manually. Cheers, Ben