From: Gavin Sinclair Date: 2002-09-13T16:00:25+09:00 Subject: Re: not grasping the method overloading/multi-dispatch thing ----- Original Message ----- From: > In Phil's example, it seems like "meth" is testing the argument's > class, not its type. According to my copy of _Design Patterns_, the > type of an object is the set of methods to which it can respond. If > two objects respond to the same set of methods then they have the same > type, even if they aren't objects of the same class. This is a bit idealised. If two objects implement the same methods (rather, the same method *names*), but completely different and unrelated behaviour, ...? > For me, testing an argument's class is a code smell. What do I care if > "s" is a Foo or a Bar, as long as it responds to the methods I need to > send it? I try to design my classes and methods so that, if I want > method "A" to accept as arguments objects that are created from > different classes, then each of the classes should implement the set > of methods that "A" will send. As far as "A" is concerned, all the > objects have the same type. Your second paragraph uses a narrower definition of "type" than your first. The first was that objects A and B respond to *all* the same methods. The second holds that A and B need only respond to the methods that method M wants to use. Going with the second definition, there's no need, then, to test for explicit class with is_a? or kind_of?; you can say: class C method M(x, y) fail TypeError unless x.respond_to? :foo and y.respond_to? :foo ... end end (Of course, y may "respond" to :foo only by implementing #method_missing, but I won't go there...) > So, for the case where you want to "overload" concat to accept EITHER > String objects or Fixnum objects: > > concat("A", "B") -> "AB" > concat("A", 1) -> "A1" > concat(1, 2) -> "12" > > then you define concat as > > def concat(arg1, arg2) > arg1.to_s + arg2.to_s > end > > Since both String and Fixnum objects respond to to_s, they're both the > same type as far as concat is concerned. This is also a highly idealised example. to_s may be widely implemented, but there's a world of difference between built-in/standard classes with their well-known methods and application code, with its targeted design, uncommon method names that *just might clash*, etc. What I'm trying to say is that if you want to demonstrate that type is nothing more than a set of strings (representing method names), then implementing "concat" is not a sufficiently strong example. Experience alone is enough to decide these things one way or the other, but I find that, at critical parts of application code, testing the explicit class of an object can be quite reassuring. Of course, sometimes I just check respond_to?, and most of the time I damn the torpedos and don't check anything :) Cheers, Gavin