in reply to Use modules or roll your own?

There is no Right answer. There are only tradeoffs.

Rolling your own means you have to explore the problem space. On the plus side, you end up with a good working knowledge of what you're trying to do -- what's possible, and what's not. On the minus side, it takes time to acquire that knowledge, and if you try to do it entirely on your own, you face an absolute mountain of special-case testing before you can truly say that you understand the space.

Using modules means you have to trust someone else to explore the problem space for you. On the plus side, it's fast, comparatively easy, and for mature modules, saves you a whole lot of 'whoops' time. On the minus side, you have no guarantee that the person who wrote the module was actually trying to solve the same problem you were, and you might not understand the problem space well enough to make that call.

To decide which option to use, look at those conditions, and decide which one offers the best benefit/risk ratio.

Core functions like printf() are so utterly common that you can be reasonably sure the canned version will do everything you want it to do. Well-defined operations, like sorting or math functions, are narrowly enough defined that they're easy to test, and are also likely to make good modules. Extremely sensitive systems, like hard real time controllers, cryptographically-secure random number generators, and concurrent transaction managers, are best left to the experts. In general, if you can specify the problem to an excruciating level of detail, you can probably find a module that already does what you want, and you'll know that it does what you want.

The looser your problem specification, the less likely you are to be sure that a specific module does exactly what you want. Should you use CGI.pm to generate HTML, or should you abandon inlined formatting entirely and go with a template-based system? If you choose to use templates, should you use HTML::Template, or do you want to do something the module doesn't support? (one of my template-based systems, for instance, emulates lambda calculus -- you can replace one marker with text that contains another marker, and the system will keep grinding away until everything has been resolved. it also uses a hierarchy of dictionaries that map markers to replacement text) Just using a module is no substitute for knowing what problem you actually want to solve.

Personally, I think the only time you're really safe deciding between modules and hand-rolled code is when you could write the module for yourself, from scratch. Until then, you take your chances. Decide which option makes you most comfortable, and do that.

If you do choose to use a module, ask yourself why you shouldn't open the source files, work through the code, and learn what the module does. It's a great way to explore the problem space without spending so much time waiting for some random glitch to expose a hole in your basic assumptions. If your answer is, "because I really don't care that much," that's fine. Just remember that when you find yourself being tempted to get religious about using that module. Getting dogmatic about something you can't be bothered to understand is pretty much the definition of cargo-cult programming.

If you don't use a module, ask yourself why you shouldn't look at other modules that do roughly the same thing, and use them as references. If your answer is "because I really don't care that much," that's fine. Just don't get grumpy when you ask questions and someone says "RTFS."