Different styles fit different stated problems. The issue is not that you're growing up from small problems to big ones keeping the same style, it is that you're cutting up big problems into small ones in a way that is a good match for your current coding style.

The specific problem that you're showing has one obvious way to tackle it, keep a hash of what files you've seen and write a double-loop. You can play with minor aesthetics like putting the inner loop into a function. But using features just to say that you're using them is bad style. And that is what trying to do anything complex on this problem is.

As for co-routine iterators, the natural place to use them is when it is easy to write a function that returns a list but you want an iterator instead. A good example is a situation where you need to parse a compressed data stream. You can easily write a function that takes the input character by character and emits uncompressed chunks. You can easily write another that takes uncompressed data character by character and parses the data. The two functions do not fit together naturally. But using yield liberally you can turn the decompressor into a function that that takes input and then emits data character by character to the parser.

However when faced with a problem like this you have a perfectly good tool to solve it - you write two programs and hook them up with a Unix pipeline. One program decompresses data, and pipes that to the second one which parses it. Voila! Problem solved. Looking at this another way, co-routines are a way to emulate a pipeline (with cooperative multi-tasking) within a single process. With the added strength that data being passed around is in the form of a native data type, not text. In other words it is more powerful in the same way that grep in Perl can be a more powerful tool than the grep utility.

But having seen that, you can also go the other way. You know that pipelines can be implemented internally within Ruby using co-routines. So you can take a problem that you'd naturally reach for pipelines on and say, "I could use a pipeline here, but let's construct it internally using co-routines". And that will work out pretty well.

But for me a more powerful realization in Ruby is that a mix-in can be used to do what you could do with tie in Perl, but better. (Look for MetaRuby.)

Cheers,
Ben