One of the problems with duck-typing: if I want a hash - or at least, something that wants to pretend it's a hash - I want to test for a hash, but in all the duck-typing languages I'm aware of, I have to test for every sodding method I want an object to respond to - or the methods I pass it to might possibly want.
The other problem is that even if it does respond to the methods - which are usually tested for by name, and not name-with-arguments - there's no guarantee that this particular object is pretending to be a hash, and not just accidentally implementing one or several methods which happen to be called the same thing as the ones implemented by the hash, but which do completely different things.
Duck-typing is supposedly useful, but I've yet to find a compelling case - and can't imagine one where this single method namespace isn't an overwhelming counterbalance to any purported advantage. Maybe I'm missing the point, but the concept of a bundle of methods, with their own namespace to distinguish them seems so necessary. Maybe call them... interfaces. So I could call object.Music::begin() if I wanted to make sure that the 'begin' was calling related to that use (perhaps the object needed to implement two different 'begin' methods), or even ask Music.implementedBy(object).
I can't decide whether this annoys me more or less than the closely related scheme of strong dynamic typing - languages which have no language support for either specifying types or run-time automatic conversions. To my mind, the only two classes of sensible languages are those which warn you up-front (at compile or analysis time) about type errors and missing methods, or those which do their best to do something sensible when you try to use a string as if it were a number or similar.
Fundamentally, when I'm coding I want the computer to do what I mean and to alert me to obvious mistakes.
I don't like languages - like Ruby - whose associated cultures encourage casual use of dynamic programming techniques, without strong expectations of good error handling or recovery.