Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

(RhetTbull) Re: Prioritizing command line options

by RhetTbull (Curate)
on Jan 19, 2002 at 02:52 UTC ( #139980=note: print w/ replies, xml ) Need Help??


in reply to Prioritizing command line options

I had this same issue recently. I rolled my own solution and it's been working well. I used Getopt::Long to parse the options on the command line and my own wrapper around Config::IniFiles to parse the INI file. Basically, what I do is create an empty hash to hold the options. Then I pass that hash to a sub that processes the command line, setting any elements in the hash that are specified there. Then I pass the same hash to another sub to process the INI file which will set options ONLY if they haven't already been set on the command line (e.g. the options are not already defined in the hash). In the main program I have this:

use ConfigIni; #my own wrapper use Getopt::Long; my %config; get_options(\%config); init_config(\%config); #now %config holds all your parameters and they're properly initialize +d -- the command line overrides anything in the ini file
These two subs are defined like this (there are probably cleaner ways to process the args but this works fine for my simple prog.)
sub get_options { #process any command line options my $config = shift; #hash ref my ($debug,$test,$ini_file,$max_files, $data_dir,$log_dir,$user,$pass,$verbose, $no_ini); GetOptions('debug=i' => \$debug, 'test=i' => \$test, 'ini_file=s' => \$ini_file, 'max_files=i' => \$max_files, 'data_dir=s' => \$data_dir, 'log_dir=s' => \$log_dir, 'user=s' => \$user, 'pass=s' => \$pass, 'verbose=i' => \$verbose, 'no_ini' => \$no_ini, ); $config->{debug} = $debug if defined $debug; $config->{test} = $test if defined $test; $config->{ini_file} = $ini_file if defined $ini_file; $config->{max_files} = $max_files if defined $max_files; $config->{data_dir} = $data_dir if defined $data_dir; $config->{log_dir} = $log_dir if defined $log_dir; $config->{user} = $user if defined $user; $config->{password} = $pass if defined $pass; $config->{verbose} = $verbose if defined $verbose; $config->{no_ini} = $no_ini if defined $no_ini; } sub init_config { #initialize the config parameters for the program my $config = shift; #hash ref my $bindir = $FindBin::Bin; #these get set no matter what $config->{version} = $VERSION; #these first two are just program + constants $config->{revision} = ($REVISION =~ /(\d+\.\d+)/) ? $1 : '?'; #if command line option -no_ini specified, then don't try to load +the ini file unless ($config->{no_ini}) { #process the ini file #if we already have an ini_file, use that one, otherwise use t +he default file my $config_file = $config{ini_file} || "$bindir/configfile.ini +"; #default name for ini file my $ini = new ConfigIni($config_file) || croak "could not load + ini file $config_file"; $config->{ini_file} = $config_file if not defined $config->{in +i_file}; #now load and set the parameters $config->{debug} = $ini->get_ini_val('Debug','Debug',0) if not + defined $config->{debug}; $config->{test} = $ini->get_ini_val('Debug','Test',0) if not +defined $config->{test}; $config->{max_files} = $ini->get_ini_val('Debug','Max_files',0 +) if not defined $config->{max_files}; $config->{data_dir} = $ini->get_ini_val('General','Data_dir') +if not defined $config->{data_dir}; $config->{log_dir} = $ini->get_ini_val('General','Log_dir') if + not defined $config->{log_dir}; $config->{user} = $ini->get_ini_val('General','User') if not d +efined $config->{user}; $config->{password} = $ini->get_ini_val('General','Password') +if not defined $config->{password}; $config->{verbose} = $ini->get_ini_val('General','Verbose',1) +if not defined $config->{verbose}; } #unless ($config->{no_ini}) #if log_dir isn't set, put logs in the same directory as the progr +am $config->{log_dir} ||= $bindir; $config->{log_file} = $config{log_dir} . "/log_file_" . strftime(" +%Y%m%d_%H%M%S_",localtime) . "$$.log"; #init anything that needs to be and might not have been done on ei +ther command line or ini_file $config->{debug} = 0 if not defined $config->{debug}; $config->{test} = 0 if not defined $config->{test}; $config->{verbose} = 1 if not defined $config->{verbose}; $config->{max_files} = 0 if not defined $config->{max_files}; #check to make sure info is complete croak "User must be specified in [General] section of ini file" if + !defined $config->{user}; croak "Password must be specified in [General] ini file" if !defin +ed $config->{password}; croak "Data_dir must be specified in [General] section of ini file +" if !defined $config->{data_dir}; } #sub init_config
For various reasons I wrote a wrapper around Config::IniFiles. One reason was to allow multivalued parameters (which Config::Ini did but had other issues). Here's that custom wrapper:
package ConfigIni; use strict; use warnings; use Config::IniFiles; use Text::CSV; use Carp; our $VERSION = '0.01'; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = {}; $self->{file} = shift || ""; $self->{ini} = new Config::IniFiles( -file => $self->{file}, -noca +se => 1); return undef if not defined $self->{ini}; bless $self, $class; return $self; } sub get_ini_val { #return a single valued parameter my $self = shift; my $section = shift || croak "must provide section to get_ini_val" +; my $param = shift || croak "must provide param to get_ini_val"; my $default = shift; #optional default value my $val = $self->{ini}->val($section,$param); if (!defined $val) { $val = $default; #undef if default no provided } return $val; } sub get_ini_val_multi { #return a list of a multi-valued parameter my $self = shift; my $section = shift || croak "must provide section to get_ini_val" +; my $param = shift || croak "must provide param to get_ini_val"; my $default = shift; #array ref to optional default values my $values = $self->{ini}->val($section,$param); my @values = (); if (defined $values) { my $csv = Text::CSV->new(); my $status = $csv->parse($values); croak "error parsing $section, $param, with value = $values" u +nless $status; @values = $csv->fields(); } else { @values = $default ? @{$default} : (); } return @values; } 1;


Comment on (RhetTbull) Re: Prioritizing command line options
Select or Download Code

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://139980]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (11)
As of 2014-12-22 16:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (121 votes), past polls