I would try to isolate your application as much as possible from the system it is being installed in. I view applications as guests on a machine - they should leave everything the way they found it.

This is clearly easier to do if everything used by your application is self-contained. When items are shared, uninstalling an application can be really difficult. Unless your application is being installed by a package manager that keeps track of how many applications are using module X (e.g. you wrapped your CPAN modules in a .deb or .rpm), you won't be able to tell if a shared module X might be in use by some other application.

Keeping every thing separate also saves you from a nightmare of version compatibility issues. You don't have to worry about your application breaking if other applications need older or newer versions of a module.

Yes, this means you might have more than one copy of module X, but at least you won't be in Perl's version of DDL/JAR hell. A common store of non-core modules for all applications is generally only a good idea if you are running a server box or test machine dedicated to a set of applications or administration scripts where you have full control over what versions will need.

Manually setting up PERL5LIB is a pain. When I produce self-contained applications, I generally put the modules in a sub-directory. I always know its location relative to the script and hard code that relative path. When the script starts up, I get the location of the script using some script magic (see below), and then convert the hard coded relative path into a real path and add the real path to @INC

Getting the actual location of the script is a bit tricky. Two things can get in the way: symbolic links and mod_perl. In *nix systems there is a long standing practice of placing a symbolic link to scripts in either /usr/bin or /usr/local/bin. Thus __FILE__ contains a symbolic link rather than the actual location of the file. To get the scripts actual location from the script alone, one has to get to the real file behind the symbolic link. To simplify the process of finding the real script, you can use the module Find::Bin

I haven't done much work with mod_perl (we use FastCGI), but as I understand it mod_perl presents another problem: scripts are loaded as modules. This means that __FILE__ is often only a partial path. To find the module's actual location, one needs to look up the module in %INC.

The script below illustrates a way to find the location of your module directory (e.g. myapp/lib) from your script file's location:

# placed in a begin block so it gets executed before we # try to load any modules. use XXX statements for non-core # modules should be placed after this begin block BEGIN { # Taint mode will complain unless you set these paths. $ENV{PATH} = ""; $ENV{CDPATH} = ""; sub calcLib { if (caller(3)) { #this is loaded as module: caller(3) returns the files caller #can't use __FILE__ between {} my $sModuleFile = __FILE__; $sModuleFile = $INC{ $sModuleFile }; return $sModuleFile =~ /bin\/[^\/]+$/ ? "$sModuleFile/../../lib" : "$sModuleFile/.."; } else { #this is the main entry point: caller(3) returns no caller #use FindBin to get the full file path of this directory #untaint FindBin::Bin my $sModuleDir = $1 if ($FindBin::Bin =~ m/^(.*)$/); return $sModuleDir =~ m/\/bin$/ ? $sModuleDir . "/../lib" : $sModuleDir; } } use lib (calcLib); }

In reply to Re: Question: Best practices for packaging scripts by ELISHEVA
in thread Question: Best practices for packaging scripts by jujiro_eb

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.