The life and death (well, deprecation) of a wrapper module

Earlier this year I was frustrated with Salvador Fandiño García's otherwise excellent Net::SFTP::Foreign package. It was in almost all respects the best choice for my current project at work, but the then-current version required me to check the return values of method calls for success or failure, and then use an error method to get any reasons for failure that might be waiting. The rest of my code used exceptions courtesy of Try::Tiny, and having to write three lines of boilerplate code for every SFTP call was getting annoying.

Thus was born Net::SFTP::Foreign::Exceptional, a very thin wrapper around Net::SFTP::Foreign that proxied all public method calls and then used a Moose after method modifier to throw an exception on any errors. (It originally used subclassing instead, but Salva set me straight on that and the less said about it the better.)

All was right with the world, or at least my project. I tweaked my wrapper a little bit, including switching to Any::Moose for situations in which Moose was just too heavy. In July, though, Salva released a new version of Net::SFTP::Foreign that threw exceptions on its own with the addition of a new autodie constructor parameter. Which is cool in that I can use one less level of abstraction in my code, but bad in that it would take a while to fix my projects to not use the ::Exceptional wrapper. And even though mine was just a pipsqueak of a module that hadn't been out for very long, it would be bad form to immediately delete it from CPAN.

Enter Dave Rolsky's Package::DeprecationManager, which provides a nice interface for marking certain method calls as "deprecated" by issuing a warning when they're called. In ::Exceptional's case, I wanted to change the code to use Net::SFTP::Foreign's new autodie parameter, but also warn that users should switch to doing that themselves instead of using ::Exceptional. So I marked new as deprecated, added the appropriate tests and docs, and released.

Total lifetime of Net::SFTP::Foreign::Exceptional: two months. But it got the job done, I learned how to (and how not to) write a wrapper module and how to manage deprecations when it's time to plan for a method's retirement. All in all time well spent.

2 Comments

The idea about adding an autodie mode to Net::SFTP::Foreign had being in my mind for a long time, probably since soon after I attended Paul Fenwick talk about autodie at some YAPC::Europe (Lisbon 2009?), but my dislike for overbloating the module even further and also laziness on my part had been stopping me for actually doing it.

You writing Net::SFTP::Foreign::Exceptional just make me reconsider it and tipped the scale in the other direction!

Leave a comment

About Mark Gardner

user-pic I'm a developer currently working as a build automation engineer for an e-commerce services company. I've been working with Perl since 1994, and although I started focused on web applications I've gradually moved into toolsmithing and custom applications. My PAUSE/CPAN ID is MJGARDNER, and I usually host my public development efforts on GitHub.