From: Brian Denny Date: 2002-09-24T01:38:02+09:00 Subject: Re: The problem with run-time type checking > Regarding (2), It seems to me that the problem isn't that the method > got an Array instead of a String, the problem is that the method got > an object that doesn't have the expected type. That is, the object > doesn't respond to the set of messages (gsub, in this case) the > method needs to send it. Presumably any object that responds to > gsub would be acceptable to the method. people keep saying that the type of an object is just the set of methods that the object responds to, but i don't buy it. def my_join (foobar, sep) result = "" foobar.each_with_index do |obj, idx| result << obj result << sep unless idx == (foobar.length - 1) end end my_join( [1, 2, 3], ',' ) => "1,2,3" my_join( "foo\nbar\nbaz\n", ',' ) => "foo,bar,baz," # note trailing comma String and Array are both of type Enumerable, and they both have a "length" method. however, the statement "String and Array both conform to an (unnamed) type 't', defined as the set of those methods which both String and Array objects respond to" is false, IMO, because the semantics of "each_with_index" are not the same, in relation to the semantics of "length", in class String as they are in class Array. if "length" were part of the Enumerable interface, i would consider the above behavior to be a defect in the library. but it's not. the point is that i, as the user of a library, can expect to be able to make certain assumptions when i know that an object is of a certain type, as defined by a class or an interface/module, that i cannot make if i just know that they both respond_to? the same symbols. -brian