Eventually I'd like to merge MooseX::App::Cmd with its Mouse counterpart, but that will require a bit more thought and planning.
]]>The first project in which I used XML::Rabbit, XML::Ant::BuildFile, is still chugging away and working well.
]]>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.
]]>It's a tiny tiny little module (less than 40 lines of code) that does a tiny tiny little thing (compare deep data structures while doing correct comparisons for unordered sets). Its main significance to me was that it exposed me to all the necessary but not difficult work of packaging up a distribution for CPAN, including documentation, tests, metadata and an installer. I went with Module::Install for the latter since it seemed like it took care of most of the repetitive work. These days I favor Dist::Zilla -- like the tagline says, it's maximum overkill and through its plugin system can automate just about anything a Perl developer needs to do. I've even written a few plugins.
Oh, and why did I write DCPSO? I was working on a tool to compare WebLogic configuration files, which are just big bags of XML with a lot of settings in no particular order. Plain old diff is no good, and even the XML-savvy variants out there (correctly) insist that element order is significant. So my program slurped in the XML and converted it to a hierarchy of hashes, lists and (you guessed it) unordered sets, reporting how and where one server was truly configured differently from another so I could fix them to be more alike.
A pretty specialized task, but I figured that the set comparison bits could be used elsewhere so I released them. And if not, hey, it got me into CPAN authoring.
]]>At mst's behest I converted it from the Moose object system to his more lightweight Moo. But now that I've accumulated a few policy modules I'd like to refactor their commonalities out into roles.
Trouble is that Moo doesn't have an equivalent to Moose's MooseX::Role::Parameterized, and I can definitely see use for that in creating a bunch of similar roles for each DBIx::Class object a policy applies to.
So what to do? Can/should I port parameterized roles to Moo, while avoiding the overhead of a meta-object protocol like Moose's Class::MOP (which Moo explicitly rejects)? Or just make a bunch of more-or-less identical roles that differ only in name and attribute content, accepting the repetition as the price of minimalism?
]]>My PAUSE/CPAN ID is MJGARDNER, and I usually host my public development efforts on GitHub.
]]>