What's the benefit of this kind of typing, though? I'm pretty much just a C hacker these days, so I'm pretty ignorant about Ruby, but does this apply to the object or to the class?
It seems simpler, especially on a conceptual level, to just initialize the the duck with everything it could possibly need to be a duck, rather than adding things dynamically.
Metaprogramming like this generally is most useful for powering "DSLs" and other ways of expressing not-quite-imperative-code in Ruby.
Yes, it is simpler conceptually. But, in Rails especially where there is a tradition of moving all your application functionality into the "model" layer, you could end up with a single class that is thousands of lines of code long. For example, a User class, with a load of code about resetting passwords, that is only used in one relatively rare circumstance.
So instead, DCI says you should separate the password-reset stuff into a separate module and only add it in when needed. Both User and PasswordReset are simpler and easier to understand and only come together when needed.
(As I said elsewhere, I prefer to wrap a decorator around the User to achieve the same thing).
It is simpler, on a conceptual level. On an implementation level however, it quickly becomes non-simple.
One of the fundamental modularity concepts is 'separation of concerns' - this isn't something you always need to do, but when a concern (a scoped set of functionality) grows large, it should be implemented separately, to keep the conceptual complexity of individual abstractions and implementations minimal.
If I implement all of the logic for handling conditions, importing data, extracting reports, managing permissions, serialization, and resource handling in the same object, it's a very complicated object. I have no way without getting a full mental model of the thing in my head that changing X about it won't break Y, or what parts of code depend on the structure of the results of calling Z.
There are plenty of ways to skin that cat, and different ones are more appropriate in different places. Often it's correct to extract the logic into a generalizable mixin, which in Ruby would be a module, and then include it into the class. Sometimes it's better to extract the logic and the concept it represents into another class that has a relationship with the original one. And sometimes it's better to separate the logic and code into a 'context' as DCI describes - I generally prefer Decorators for this, but the Rails community seems to lean toward using modules here also, largely on the weight of DHH's opinion (app/concerns/).
Go is way faster than Ruby and extensively uses duck typing everywhere (but is also statically typed and not interpreted-). My point is duck typing is not the reason Ruby is so slow.
Delegation (especially with the extreme simplicity of SimpleDelegator) seems like the obvious solution here, at least to me, but some people prefer to use cache-busting mixins instead.
Is your app CPU-bound? If so, then DCI probably isn't a great idea for you. In fact, building it in Ruby may not be the best idea.
But if your app is IO-bound (like most Rails apps), huge and it takes new developers weeks to get up to speed, then the gains from having a simple, modular code-base should save you developer-time (and hence salaries), which are much more expensive than CPUs.
Having said that, I tend to use SimpleDelegator instead of dynamically injecting stuff into objects.
EDIT: added 'ruby not being the best idea if CPU bound'
There's even a protocol for notifying instances that their class has changed so they can make any necessary adjustments: http://clhs.lisp.se/Body/07_bb.htm