This is part II of my blog on my version woes. Part I can be found here.

Let’s review some of the issues I identified in part I.

  • What version of perl should I be using for development?
  • If I publish a CPAN module, what version(s) of perl should I support?
  • What version of a dependency do I really need in my module?
  • What should I do if I receive errors in the CPAN Testers Report?
  • Should I include core modules as dependencies? (the answer is not as obvious as you might think)

What version of perl should I be using for development?

It depends. For new development, it would make the most sense to use a current version of perl (5.38.0), but when do we truly do new development in the Perl language these days? Even in companies with sufficient Perl programmers it’s a risk to start new applications in a language that increasingly is being ignored by both vendors and new developers. Libraries for APIs are tough to come by and young developers are not making it a priority to learn Perl. That’s a shame, because learning some Perl is like learning vi. You’ll see it on almost every Linux based system you touch. It’s ubiquity demands some awareness.

In the old days of computing the saying was “No one ever got fired selecting IBM.”. I think one can use that same sentiment when talking about language choices for new applications. “No one ever got fired for selecting Python, C# or Java.”. It would be a questionable choice to select Perl for new development today due to the obvious issues we all recognize.

  • Lack of vendor support for new APIs
  • Scarcity and aging of competent Perl developers
  • Cost of Perl developers
  • Unknown, confused trajectory for the language
  • All of the inherent deficiencies of the language itself (see Curtis Poe’s excellent video describing Corrina’s attempt to address these issues)

So, for new development it seems that the majority of shops that might have Perl developers might still choose to look elsewhere. Perl work then seems to be relegated to maintaining and enhancing legacy Perl applications that would be difficult, costly or impossible to rewrite in a more modern language. Still, one could conceivably review the version of perl being used and choose a more modern one as a target for enhancing the maintainability of the application. But that comes with its own set of problems.

Will the application work if I migrate it to a new version of perl?

Who knows? You just have to try it…but:

  • Should I go straight from 5.x to 5.38.0?
  • There are no unit tests for the scripts and modules that comprise the application
  • There are no integration tests that test the features of the application
  • The application relies on older CPAN modules with undocumented version dependencies (and worse unknown dependencies for building said modules)
  • The application also relies on core modules, some of which may have been removed from the current version of Perl
  • The application uses the system perl executable with unknown dependencies on its attributes

Even attempting to create a new development environment for legacy Perl applications using the same version of perl can be difficult if not impossible. As I have discovered in my most recent job, building CPAN modules that rely on C libraries is not a particulary easy exercise. For example, attempting to build JavaScript::V8 required hours of forensics and internet time travel…ultimately resulting in this solution.

FROM amazonlinux:2
COPY epel.repo /etc/yum.repos.d/epel.repo
RUN yum install -y wget 'perl(App::cpanminus)'
RUN yum groupinstall -y 'Development Tools'
RUN cpanm -v App::cpanminus
RUN wget
RUN rpm -ivh libicu-4.2.1-14.el6.x86_64.rpm
RUN yum install -y libuv
RUN yum install -y v8 v8-devel 
RUN cpanm -v JavaScript::V8@0.09

Of course, the obvious question is “Why are you using JavaScript::V8?”.

Reminder: This is a legacy application with no documentation, no unit tests and no integration tests. Changing anything in the application is like walking in a mine field with size 14 boots.

So, what perl version should you use?

Since I was unable to build a necessary dependency on a system with version 5.36.0 of perl, the decision of which perl version to use for this application was made for me…stick with the version running in production for now.

For legacy applications my approach has been more or less the trial and error approach…optimistically trying to update the version of perl and seeing where it takes you. Most of the time with legacy applications it doesn’t take you far. I try to build and unit test (to whatever degree possible) as much of the application as I can with a more modern version of perl, its core modules, and the latest version of any CPAN dependencies. Until that process is proven successful (or not) the application is built using the versions of modules and of perl that are currently running in production.

Here are the basic steps I have been using with legacy applications.

  1. Identify the artifacts of the application (not always as easy as it sounds)
  2. If the source is not yet under source control, create a git repository and create a baseline. Don’t try to do anything fancy at this point - just reflect the structure of the application as it is laid down on the target servers in your repository
  3. Identify all dependencies (core and CPAN modules). Create a manifest of dependencies and versions being used in the production environment.
  4. Run perlcritic to gauge the mess - save the results to measure your progress in the cleanup process
  5. Try to build a containerized (Docker) version of the application in the currently running (older) perl version using your original manifest.
  6. Do a gap analysis between versions being used and the latest version of the modules.
  7. Try to build the application and all dependencies in the newer target version using the latest version of core and CPAN modules.
  8. Test components and/or the application as a whole if possible identifying version problems and incompatibilities with the target perl version.

You will first encounter problems trying to build a containerized version of the as-is application, especially if the legacy application resides on a production server that has been poorly maintained. Poorly maintained being defined as one or more people having manually installed things over the years without of course documenting what they have installed or what additional dependencies were needed. If you can get by this step and have successfully built the application in a containerized environment, then you at least have the basis for a more modern approach to software development.

  • development environments isolated from test or production system that are relatively easy to create
  • a build system that can be woven into you CI/CD pipeline
  • documentation of dependencies
  • a stable base for creating unit tests

Some Useful Tools for Legacy Applications

more next time…

Next post: The Trouble With Versions (Part III)

Previous post: The Trouble With Versions (Part I)