http://www.perlmonks.org?node_id=994067

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

I have an application that manages a database of entries used to build a list. It has a fairly detailed config file written in YAML that it loads via $FindBin::Bin. In addition, it has several state tracking files that finds similarly. Initially, only the one application automatically added to the list, but now a suite of tools has become necessary to do different things with this database beyond simple, automated modification. I've moved all of the shared code to a module, but I'm curious what to do with the config file. None of the values stored in the configuration are necessary outside of the scope of the module, but I'm not sure that moving it into a __DATA__ section is what's called for, nor am I sure what to do about the state files. Does anyone have any experience with this? What did you do?

Replies are listed 'Best First'.
Re: Refactoring conf-driven app into a module; what to do with the config?
by moritz (Cardinal) on Sep 17, 2012 at 18:27 UTC

    First of all you should be clear about "config file" versus "data file". If another user installs the same module on another machine, will he have to adapt some of those values? If yes, it's config. If not, it's data.

    Second point: Just because it's a module doesn't mean that by some magic it shouldn't have to have configuration or data files. There are good use cases for those. So I'm not quite sure what your question is. Yes, I have written code that depended on data files and configuration files. Yes, one can handle that.

    If your module has a build system similar to most CPAN modules, File::ShareDir can help you locating the files.

    The needs regarding configuration can vary drastically by application, but they have in common that for most needs CPAN already has a solution.

      "Just because it's a module doesn't mean that by some magic it shouldn't have to have configuration or data files. There are good use cases for those. So I'm not quite sure what your question is."

      You seem to have a pretty good handle on either possibility, actually. Also, you seem to have some insight into misunderstandings I might have made, would you mind addressing those for posterity? Note that I wasn't asking if one could handle that, but how.

      "The needs regarding configuration can vary drastically by application, but they have in common that for most needs CPAN already has a solution."

      Exactly why I'm here...or why most people are here: for some suggestions and advice on best practices used in certain circumstances. Having reflected upon my question in light of your observations, I'm thinking that this falls into the "data file" category. Occasionally certain values will need to be changed, but this would be on an application-wide basis, not on a user-by-user basis.

      The module does not require a build process because it isn't intended for distribution, nor has it become generally useful enough to merit it, so perhaps File::SharDir is not the best solution.

      Do you have any further suggestions, given my clarification?

        In your case I'd probably just hardcode a path, like /usr/share/yourmodule/ and put the data file(s) there. Unless they are pretty small, in which case a __DATA__ section would be even easier. Then change your module to read them when it needs them.

        That's the "how" if you don't follow the File::ShareDir route -- though personally I think that even simples modules should have a proper build/install system (via Module::Install or Module::Build), because it's easy to set up and easy to use.

        Occasionally certain values will need to be changed, but this would be on an application-wide basis, not on a user-by-user basis.

        This indicates that it's not a one-off script, but something that is developed and/or maintained over a longer period of time. I'd definitively go the Module::Install/Module::Build route for that, and use File::ShareDir to locate the data files. But your mileage my vary, of course.

        The module does not require a build process because it isn't intended for distribution, nor has it become generally useful enough to merit it, so perhaps File::SharDir is not the best solution.

        File::ShareDir::ProjectDistDir then :)

Re: Refactoring conf-driven app into a module; what to do with the config?
by blue_cowdawg (Monsignor) on Sep 17, 2012 at 18:36 UTC

    As moritz already pointed out, if the information is static then what you have is a data file. In that event why not embed it into your module somehow?

    If the end user is expected to modify the information somehow (DB name, DB host, user, password et. al.) then you should be using a configuration file. YAML, JSON, XML or just a good old fashioned text file with key value pairs is good. Another technique I've seen more than once is to create a file that looks a lot like a Perl module (in fact is) or plain Perl code to be read. Example:

    package MyConfig; # # For the record: fixed the following 4 lines since my fingertips dec +ided to do something # other than what my brain was telling them to. s/my/our/ our $datahost="blah.foo.com"; our $datauser="user"; our $password="s3cr3t"; our $database="thedata"; 1;
    which is then used thusly:
    |random handwaving here... use MyConfig; my $host=$MyConfig::datahost; my $user=$MyConfig::datauser; my $pass=$MyConfig::password; my $database=$MyConfig::database; | now do something with it...

    Personally for my own uses I use XML files and XML::Simple to load them.


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg