As a light disclaimer, I am still working on adding duck typing to my skill set. As a result, this is a very silly way for me to gather my thoughts in one place. There are no examples or even code snippets, but abstract and ridiculous examples of patterns that help me when designing and writing code that could benefit from duck typing.
As an interpreted, dynamically typed language Ruby is built to make developers' lives as easy as possible. Unfortunately, this relies on the developer knowing and being willing to shift their habits to follow these best practices. This does not make your life easier in the short term. Developers being mortal and mostly human, have a hard time shifting their focus from short term solutions to generalizing their problem for others. It is far easier to say "My bird quacks and walks like a duck, so my bird is a duck. Future birds are someone else's problem." Besides you'll be at a different duck farm identifying different ducks in a few years. That's a hard habit to break, but it will make future developers less likely to hold grudges against you.
OOP lends itself to bad design habits by creating problems whose easiest solutions are concrete. An answer to a single case ships features now while creating extensibility problems later down the roadmap. Concrete code and knowing too much context about other objects are examples of temporary solutions. These create technical debt and while they are convenient now, result in difficult to change code bases with far reaching dependencies.
One of the marks of good design is trust. Concrete code trusts no duck. It wants very specific things in a very specific order. It interrogates every duck about all their duck habits in a set order. If a bird quacks when you ask them to waddle they won't pass your duck test. It's a very inefficient, error prone form of identification. As a duck farmer, when customer asks for a bird that waddles and you winnow by birds that also quack you lose out on getting rid of Steve the goose who always attacks you when you try and feed him. Duck typing allows for flexibility in implementation and request fulfillment. Focusing only on the specific request allows you to be more flexible when required.
Narrowing objects that can interact with each other in specific ways narrows your future choices by relying on too much context. Earlier we were relying on too much context when we knew that Steve waddled and is a feeding time terror. That 'and' is important. It is descriptive of Farmer who is strongly coupled to it's Duck and Geese objects. Duck typed code, unlike farming, should know as little about the objects as possible. 'And is a feeding time terror' is too much context. The bare minimum is exactly the amount we need to create something that is flexible. The chain of trust should extend from the Customer to the Farmer to the Thing that Waddles.
Duck typing allows you to expand your software duck farm easier by requiring the least amounts of change to fulfill the requirements of it's application.
If you need a more technical, less silly discussion of duck typing Sandi Metz's Practical Object-Oriented Design book, specifically chapter 5, contains very helpful examples and a more technical look at Duck Typing.