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

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

In one of scripts, wanted to add facilty to set options via configfile alongside getting it from cmdline.

I looked at bunch of different ways to set options using configfile and cmdline.
  1. simple perl file read for configfile and use of getOpt::Long for cmdline options
  2. AppConfig for both configfile and cmdline args
  3. configReader:: Did not dwell much into it
I am leaning towards 1) since it is simple and does what I want.

Now main question:

one thing that I did not like in all of them was the fact that you had to deal with same varible three times.

  1. first, you declare the variable
  2. then, you pass it as Hash to the function that reads it ..
  3. then, again deal with same variable in the usage()...

Is there a way I have to deal with the variable just once??

I took a brief look at GetOpt::Declare() and It seems that helps reduce the dealings to twice ...But then it is not as powerful as AppConfg and does not allow reading files...

Any smart way to reduce dealing with variables ?

Thoughts on ways to read arguments via configfile also welcome/appreciated.

Replies are listed 'Best First'.
Re: Smart way to deal with cmdline Args?
by chrestomanci (Priest) on Dec 07, 2010 at 22:27 UTC

    Just an idea, but getOpt::Long normally takes a hash reference as the first argument, and that hash can contain default values before the options, but it should be possible to populate that hash from a config file.

    The normal way I use getOpt::Long is with code like this.

    # Setup the raw options from the system defaults. my $raw_opts; $raw_opts->{'help'} = sub{ pod2usage( -verbose => 0 ) }; $raw_opts->{'man'} = sub{ pod2usage( -verbose => 2, -exitstatus => + 0 ) }; $raw_opts->{'verbose'} = sub{ $logger->more_logging(1) }; $raw_opts->{'quiet'} = sub{ $logger->level($FATAL) }; # Use the store in hash form op GetOptions, with references to excepti +ons setup above. GetOptions( $raw_opts, 'help|h', 'man', 'verbose+', 'quiet', 'username=s', 'password=s', 'password_file=s', # Other options. ) or pod2usage( -verbose => 0, -message => "incorect options" ); # Check the options. # Rest of the program.

    I am thinking that a simple way to add support for config files would be that after the config hash has been declared and the defaults loaded, you could load config settings from something like Config::Trivial. After the command line settings have been parsed and checked for correctness, you could then store them again.

    I have done this sort of saving and restoring of configuration preferences using this patten in the past, however, I have always ended up modifying it into something more complex, as the needs of the script have increased.

Re: Smart way to deal with cmdline Args?
by Anonymous Monk on Dec 07, 2010 at 22:24 UTC
    1. first, you declare the variable 2. then, you pass it as Hash to the function that reads it .. 3. then, again deal with same variable in the usage()... Is there a way I have to deal with the variable just once??
    Maybe foobar(\my %hash); or foobar(my $href = {...}); can get you part of the way there.

    I only glanced at them, but you might make use of Getopt::ArgvFile (specifying files that are automatically read?) or Getopt::Lucid (which talks about reading in config file in its synopsis).

      Great. Thanks. I am now using hash to collect values from options so I do not have to declare it explicitly so that makes it 2 dealings with options, rather than 3.

      I am going to look into other monks reply about pod2usage and see if helps me reduce two dealings to one.

Re: Smart way to deal with cmdline Args?
by kevbot (Vicar) on Dec 10, 2010 at 08:52 UTC
    If you are familiar with Moose then I would recommend taking a look at MooseX::GetOpt. It is great for rapidly creating command-line applications and it has options for dealing with config files.

    From the MooseX::GetOpt documentation: If your class also uses a configfile-loading role based on MooseX::ConfigFromFile, such as MooseX::SimpleConfig, MooseX::Getopt's new_with_options will load the configfile specified by the --configfile option (or the default you've given for the configfile attribute) for you.