mandog has asked for the wisdom of the Perl Monks concerning the following question:

We're moving our SQL to a separate SQL::Library file, for the same sorts of reasons our HTML is in HTML::Template files.

We're also separating out our .pm files into a cpan package. We are feel standards-complaint and smug about running tests from t/ and listing dependencies in Build.PL. However, we haven't actually built the package yet.

Our application files *.pl, some static html, html templates are in a seperate directory. The application files depend on library but the library files (*.pm) & their tests shouldn't depend on the application files.

We could put the SQL::Library in the application conf dir, but then any (eventual) cpan module will have external dependencies.

We could put them in the same place as ..../lib-our-app/lib/*.pm. Then when our module is installed by cpan or make/make install, we'll have to search through @INC to find our SQL::Library file at runtime.

Thinking about it, the same reasoning applies to the HTML::Template files

I'm inclined to believe that a web application is a square peg for the round cpan module hole and that our application *.pm files should go in /var/lib/our-app-name/lib/ and our template and SQL::Library files should go in /var/lib/our-app-name/templates/


Replies are listed 'Best First'.
Re: put SQL::Library file where?
by SilasTheMonk (Chaplain) on Oct 03, 2009 at 17:20 UTC

    One critical consideration is that there is no way for a hacker to see your .pm, your sql files and any other files that they have no right to see. .pm and SQL files would be especially useful to a hacker as they would pretty much hand him the keys. Clearly you are keeping them out of the document root directory which is good. Apache has all sorts of ways mapping odd directories into user visible web space. Are you confident that you have none of these mapped so that your .pm and SQL files can be exposed? Also can you use the UNIX file permissions to add further protection. This depends a lot on to what extent this is a shared server. If it is a shared server can you protect yourself further by using suExec?

    Edit I have reread your post again. You are planning to publish your .pm files to CPAN. I assume by this you mean the reusable components. With regard to those files I don't really see the issue. Files generic enough to be published to CPAN can go whereever perl modules normally go.

    Edit 2 The more I think about the more confused I am about this. What are your priorities?

    1. Security? Something you definitely need to think about.
    2. Maintainability. I think this was your question. Actually you seemed to be referring to the specifics of your situation which you should probably not give us to much detail on.
    3. Publishing reusuable components to open source. If you have some I don't see what the question is. If you don't, don't mention CPAN.
    4. Regression testing. Can I recommend Test::Regression. Just a module I stumbled across somewhere. ;-)

      Yes, creating rational directory structure for our application is our primary goal. We want to put things in a standard place, so people that understand the standards, understand our application setup. We also want to structure our directory tree to facilitate building standard packages so people can install our software one their own servers.

      Thank you SilasTheMonk and jakobi, I now realize that we don't want to publish a cpan module. We have .pm files but none of them are of interest outside our application.

      The docuument we want is Debian (draft) webapp manual

      The issue is that when installed our .pm files will end up in any one of:

      ./ /usr/local/lib/site_perl /etc/perl /usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl

      We can say:  use OurApp::LibName; and find our libs

      We can't say  my $sql_lib=new SQL::Library {lib=>'sql.lib'}; We have to say: my $sql_lib=new SQL::Library {lib=>'/full/path/to/sql.lib'}

      We could write code to search @INC for our file, but that doesn't seem right

      There is little or no code in our libraries that is useful outside our application, so publishing to cpan might no make sense. Following the conventions of a cpan package may make our life easier even if we don't ever make a package.

        So as I understand it the question is how to rationalize the configuration of your app. Where would you like your config file to be? I think you need to first of all figure that out. Then you need to figure out how to inform your app of that location. You may want to think about what your ideal format would be. There are probably several modules in CPAN to read those config files. One of your lines would be the location of your SQL::Library file. So you code might end up as
        my $config = [....code to read config file]; ..... my $sql_lib=new SQL::Library {lib=>$config->sqllib_path()};
Re: put SQL::Library file where?
by jakobi (Pilgrim) on Oct 03, 2009 at 18:11 UTC

    If the SQL::Library isn't for CPAN, then it is more of an layer of the app above the CPAN modules used (or currently being refactored out from old code).

    Can you think/structure app + SQL::Library as a kind of 'user' providing code or code refs for use in hook functions provided by lower level modules? Alternatively, with similar effect: can you think of this as sub-classing the cpan modules?

    If I correctly see the issue, shouldn't such an approach solve at least the 'future CPAN module depending on external files not in CPAN'?


    ps: if you've split the modules in one for CPAN, one for internal use and both are installing in @INC following CPAN guidelines, why do you need an explicit search of @INC? Unless for instance-specific templates. And that would be application-instance-specific app-configuration, and not use Perl's @INC at all.