From: Gavin Sinclair Date: 2004-06-06T13:35:03+09:00 Subject: Re: How to ducktype a Hash? On Sunday, June 6, 2004, 10:30:29 AM, Sean wrote: >> This is even worse than object.kind_of(Hash). The whole point of "duck >> typing" (as I understand it) is that you don't check if an object has >> certain methods. You just use them. Ruby will throw an error if there's >> a problem. > Which always sounded fine to me until I was actually exposed to this kind of > "typing." The problem is, the methods [] and []= are there, they just don't > do what I need them to do. Duck typing completely and utterly don't help, > and Ruby has no way to tell me when an object's [] and []= are hash-like or > something else. My solution is going to end being something like "tagging > all objects that I know in advance to be hash-like, and then looking for that > tag at that particular point in my code." That's a kludge to me. Well, that's like static typing, which is a kludge to many people. The "problem" is that Ruby allows you to decide on the level of type-/class-checking that you want. If this were a static OO language (take Java for example) then you would have to declare your method as taking a Map parameter, and it sounds exactly like what you want. Then any piece of code that called your method would need to ensure it was passing a Map. All that's doing is "tagging all objects that I know in advance to be map-like, and looking for that tag at that particular point in your code". The difference is that the compiler is doing the checking, and the objects are marked from the outset because they implement a certain interface. So if interfaces is what you want, then use them. If the fact that you have to do the work rather than the language makes it a kludge, then so be it. But Ruby's getting along fine without taking the narrow road. Cheers, Gavin P.S. If it were my code, I would simply do class-checking in that particular instance: raise an error if it's not a Hash (just at that point, not everywhere in my code). Then, when it so happens that some other type of object wants to get through, I'd weaken the interface or strengthen the objects. It may be the easiest thing to do to force "clients" of the code to pass in a hash. Anything hashlike should have a to_hash method. Perhaps you can use that method as your hash-like indicator. (Remember, though, that Hash also has a to_a method...)