Flavio Poletti

Irreducible Perler.

Wrapper...l

wrapperl is a (Perl) program lets you wrap another Perl program with some local-specific configurations.

Why would you do this, e.g. as opposed to modifying the hash-bang line or setting PERL5LIB, or calling the perl executable directly? Well, lazyness of course, but also the fact that in different environments the same program might need different configurations, and changing those configurations possibly in many little Perl programs quickly becomes an error-prone hassle.

wrapperl provides you with a consistent, minimal and easy to setup way to concentrate local-specific configurations in wrapperl.env file, and be sure that you will call your Perl program(s) with the right setup every time.

This article contains only a brief extract from the documentation to get your feet wet; you can find the whole thing on the GitHub repository.

Installing

Installion is easy: download wrapperl from here and put it somewhere in the environment(s) where you need it. It is not necessary to put it in a directory in the PATH, although it is suggested in order to access all functionalities.

A Complete Example

Sometimes an example is worth a thousands manuals.

A few assumptions

Let’s make a few assumptions:

• you will write your program prg.pl. If you don’t even want to write one, you can copy and paste this:
#!/usr/bin/env perl
print "using perl '$^X', \@INC contains:\n"; print "- '$_'\n" for @INC;
• you do your coding in a development environment where:
• you develop prg.pl inside directory /home/me/program
• perl is located at /home/me/perl/bin/perl
• the libraries you need are stored in non-standard positions /path/to/some/lib and /path/to/another/lib
• you deploy your program in a production environment with a different setup, namely:
• your program prg.pl is deployed in directory /app/program
• perl is located at /approved/perl/bin/perl
• the libraries you need are all stored in /approved/lib

This is what how you start in the development environment:

me@devhost /home/me/program$ls -l -rwxr-xr-x 1 me me 74 Apr 23 22:28 prg.pl This is what how you start in the production environment: me@production /app/program$ ls -l
-rwxr-xr-x 1 me me 74 Apr 25 20:51 prg.pl

In both environments, you create a symbolic link named prg pointing towards wrapperl. The link is located inside the same directory as prg.pl.

This is what you end up with in the development environment:

me@devhost /home/me/program$ls -l lrwxrwxrwx 1 me me 8 Apr 23 22:51 prg -> /home/me/bin/wrapperl -rwxr-xr-x 1 me me 74 Apr 23 22:28 prg.pl This is what you have in the production environment: me@production /app/program$ ls -l
lrwxrwxrwx 1 me me  8 Apr 25 20:51 prg -> /usr/local/bin/wrapperl
-rwxr-xr-x 1 me me 74 Apr 25 20:51 prg.pl

Step 2: create wrapperl.env files

In each environment (development and production in our example) You create the wrapperl.env file, which will hold configurations that are specific for the environment it is located into. We will put it in the same directory as prg and prg.pl.

wrapperl.env is a standard Perl file, where you can:

• set the environment variable PERL5LIB to point towards the library paths you need for loading your modules, and
• set a specific perl binary by means of the $PERL variable For our example, this is what you end up with in the development environment: me@devhost /home/me/program$ ls -l
lrwxrwxrwx 1 me me  8 Apr 23 22:51 prg -> /home/me/bin/wrapperl
-rwxr-xr-x 1 me me 74 Apr 23 22:28 prg.pl
-rwxr-xr-x 1 me me 90 Apr 22 12:35 wrapperl.env

me@devhost /home/me/program$cat wrapperl.env$ENV{PERL5LIB} = '/path/to/some/lib:/path/to/another/lib';
$PERL = '/home/me/perl/bin/perl'; This is what you have in the production environment: me@production /app/program$ ls -l
lrwxrwxrwx 1 me me  8 Apr 25 20:51 prg -> /usr/local/bin/wrapperl
-rwxr-xr-x 1 me me 74 Apr 25 20:51 prg.pl
-rwxr-xr-x 1 me me 66 Apr 25 20:51 wrapperl.env

me@production /app/program$cat wrapperl.env$ENV{PERL5LIB} = '/approved/lib';
$PERL = '/approved/perl/bin/perl'; So yes, they two setups are mostly the same, except for the contents of the wrapperl.env files, each containing configurations that are environment-specific. Now, you are ready to run your program in either environment, just remember to execute the symbolic link to wrapperl instead of your program. In the development environment: me@devhost /home/me/program$ ./prg
using perl '/home/me/perl/bin/perl', @INC contains:
- '/path/to/another/lib/i686-linux'
- '/path/to/another/lib'
- '/path/to/some/lib/i686-linux'
- '/path/to/some/lib'
- '/home/me/perl/lib/site_perl/5.18.1/i686-linux'
- '/home/me/perl/lib/site_perl/5.18.1'
- '/home/me/perl/lib/5.18.1/i686-linux'
- '/home/me/perl/lib/5.18.1'
- '.'

In the production environment:

me@production /app/program$./prg using perl '/approved/perl/bin/perl', @INC contains: - '/approved/lib/i686-linux' - '/approved/lib' - '/approved/perl/lib/site_perl/5.18.1/i686-linux' - '/approved/perl/lib/site_perl/5.18.1' - '/approved/perl/lib/5.18.1/i686-linux' - '/approved/perl/lib/5.18.1' - '.' Can you PATH? If you can put wrapperl somewhere in the path (or in the same location in every environment), you can even spare the symbolic link. Just point the hash-bang to wrapperl and you’re done: #!/usr/bin/env wrapperl print "using perl '$^X', \@INC contains:\n";
print "- '\$_'\n" for @INC;

As an added bonus of this approach, you can even name the program whatever you like!

Where Do We Go From Here?

I can’t say that we have only scratched the surface, because the example above covers the main use case for wrapperl. On the other hand, it is true that it can offer more, namely:

• an easy way to call perl based on the configurations found in wrapperl.env
• an easy way to call perldoc in a similar way, which of course allows you to access the documentation of the modules installed in the local libraries
• a way to figure out which wrapperl.env file is in use for a specific symlink

and probably something more. You can read the full documentation here and peruse/fork the code repository at wrapperl’s GitHub repository.

For now… That’s all folks!