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

A distribution I maintain, ExtUtils::ModuleMaker, has an interactive mode that uses selections entered by the user at a prompt to build files and directories. The user's selections override default selections hard-coded into the module itself.

It has been suggested that in a future version of the distro, I allow the user to save the selections entered as new default values (to make using the interactive mode even lazier than it is now), and that I save those new default values in a .rc file, similar to .bashrc or .vimrc which the user will store in his/her home directory. Subsequent invocations of the module's interactive mode will extract default values from the .rc file rather than from the module itself.

There are several different ways of writing such configuration files (Perl scripts required in to a program, Windows-style .ini files, Apache-style .conf files, XML files) and quite a few CPAN modules designed to read such files. I'm not concerned here with the merits of these different approaches, as they've been well discussed on Perlmonks going back five years.

My question is simpler and lazier: Can anyone point me to a CPAN module which already does this? I.e., Is there a CPAN module which already stores a config file in a user's home directory as part of its normal operation?

I'd like to reinvent the wheel as little as possible. Thanks in advance.

Replies are listed 'Best First'.
Re: Installing a config file during module operation
by CountZero (Bishop) on Aug 07, 2005 at 16:42 UTC
    I doubt there is one module which can do that in a system-independent way. The whole idea of a "home directory" is already rather foreign on Windows. I would go for storing the defaults in a Perl-module (config.pm?) which you place somewhere in the usual Perl/site/lib hierarchy close to where your module will reside. I think that is the only way to do it in a portable way. You will of course have to key the defaults in this module with the user's id to enable you to store multiple users in the same module.

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

      As the guilty party for suggesting a config file to Jim, I should add that I was hoping that Config::Find could be used to provide a system independent way to locate a config file. The heuristics for Windows are described at Config::Find::WinAny. Has anyone tried out this module?

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

        I did cast a look at that module, but since it uses the return value of Win32::GetFolderPath(CSIDL_LOCAL_APPDATA) to find a good place to store the config files and Win32::GetFolderPath(CSIDL_LOCAL_APPDATA) on my Windows XP Professional points to C:\Documents and Settings\kjm\Desktop, all the config files would be put on my desktop!

        Obviously that is not a good solution. Perhaps there is something wrong in my setup, but if the module relies on something which can be so easily broken, I rather pass.

        Update: I checked the module once more and the latest version (0.18 or 0.21) does import the constant, so it seems OK.

        CountZero

        "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

      Why can't you just do something like this? Use a trivial API:
      get_value_names($config_name); - returns array with names of stored parameters get_value($config_name, param_name); set_value($config_name, param_name, value); clr_config($config_name);

      With all due respect (and condoleances) to the people (*) who knows more about the registry than me, but why can't you just dump the values in registry keys on Windows -- and a nice config file under Unix?

      It seems the obvious and trivial way of doing it? What doesn't I understand?

      Update:
      Just use a tie to a hash for API. No fuss, no muss. Also, add export/import to text file under Windows.

      (*) Millions of people, literally :-)

        As a recovering Windows user, I have to say that playing with the registry is just asking for trouble. It only takes a very minor mistake to corrupt the registry, and that could leave your system unbootable. Ask me how I know this ;-)

        If you *do* want to play around with the registry, make sure you've made a good backup of it, and also review (before you begin) how to restore a corrupt registry. It can be done, but it's hard to read the help files once you've lost the ability to boot.

Re: Installing a config file during module operation
by dbae (Beadle) on Aug 07, 2005 at 16:48 UTC
    The cpan command uses /usr/local/lib/perl5/5.8.7/CPAN/Config.pm on my system. The user's version of this is at ~user/.cpan/CPAN/MyConfig.pm

    I haven't read the code, but I believe that the writing of the user version is done in /usr/local/lib/perl5/5.8.7/CPAN.pm so you could look at that.

      This might work on a non-Windows system, but on Windows it is definitely broken.

      To find the "home"-directory, CPAN::Config->load uses $ENV{HOME} which on my Windows XP Professional box simply doesn't exist.

      Windows XP is able to store multiple user-profiles but does so in the directory indicated by $ENV{USERPROFILE}.

      CountZero

      "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

Re: Installing a config file during module operation
by jhourcle (Prior) on Aug 07, 2005 at 22:36 UTC

    There are two that I can think of that prompt for configuration details on install, and keeps track of them -- libnet (which stores its config in Net/libnet.cfg in your perl module path) and CPAN, which writes to both CPAN/Config.pm and $HOME/.cpan/CPAN/MyConfig.pm

      Thanks for this and the other comments. My inclination is to try to keep this feature as simple as possible, which implies (to me, at least) not loading up the CPAN distribution with non-core modules which are only used to install one file. Particularly if those modules themselves have dependencies. I'll look at how libnet and CPAN.pm do it on Windows and Darwin, then try to borrow what seems most useful.

      In any event, I have a couple of other refinements I need to do before I get to this one, so I have time to think about it. I'll let you all know what develops.

      Thanks for responding.

      Jim Keenan