sub getArgs { # 1. Declare internal defaults to use for any atributes not on the command line or in the user's preferences. # Format is: name (hash key), default value, comment (for the stored config file). my $user_prefs_file = $HOME.'/.application_name.prefs'; my @system_defaults = ( [ 'verbose', 1, "The Verbosenes. The script should be silent if verbose=0" ], [ 'parse_schedule_file', 1, "If true, parse the schedule file" ], # ... etc. ); # Setup the raw options from the system defaults. my $raw_opts; my $user_prefs = readDataFile( $user_prefs_file ); # Load user preferences, & over write defaults. foreach my $ent ( @$system_defaults ) { my($key, $value, $comment) = @$ent; # The comment is not used at this stage. if( defined $user_prefs->{$key} ) { $raw_opts->{$key} = $user_prefs->{$key}; } else { $raw_opts->{$key} = $value; } } # 3. Parse the command line, overiting options from the user prefs & internal defaults. my $store_prefs; $raw_opts->{'store_prefs'} = \$store_prefs; $raw_opts->{'help'} = sub{ pod2usage(-verbose=>0) }; $raw_opts->{'man'} = sub{ pod2usage(-verbose=>2, -exitstatus => 0 ) }; # Use the store in hash form op GetOptions, with references to exceptions setup above. GetOptions( $raw_opts, 'help|h','man','verbose!','store_prefs','flush_cache', 'parse_schedule_file!', # ... etc. ) or pod2usage(-verbose=>0, -message => "incorect options"); # Store the updated user preferences if required. if( $store_prefs ) { store_user_prefs( $raw_opts, $user_prefs_file, $system_defaults ); } # Delete special references delete $raw_opts->{'store_prefs'}; delete $raw_opts->{'help'}; delete $raw_opts->{'man'}; # All done, return return $raw_opts; } sub readDataFile { # Reads a perl data structure from a file. my( $fileName ) = @_; return undef unless -r $fileName; # Quick check the file exits. open INFILE, "<", $fileName or die "Error, unable to read $fileName $!"; my $fileText = join('', ); close INFILE; return eval( $fileText ); } #### sub store_user_prefs { my ( $raw_opts, # Options hash, amalgamanted from system defaults, prevously stored preferences, and the command line. $user_prefs_file, # File to store the option in. $system_defaults, # System defaults. Used to provide an ordered list of options to store with comments to store against them. ) = @_; open OPTS, '>', $user_prefs_file or die "Error saving preferences in $user_prefs_file, $!"; print OPTS "#!/bin/perl\n"; print OPTS "#\n"; print OPTS "# user preferences file. Edit with care.\n"; print OPTS "\n{\n"; foreach my $ent ( @$system_defaults ) { my($key, $value, $comment) = @$ent; print OPTS " # $comment\n"; if( 'ARRAY' eq ref $raw_opts->{$key} ) { my $list = '\''.join('\', \'', @{$raw_opts->{$key}} ).'\''; printf OPTS " '%s' => [%s],\n\n", $key, $list; } elsif( 'HASH' eq ref $raw_opts->{$key} ) { printf OPTS " '%s' => {\n", $key; printf OPTS " '%s' => '%s',\n", $_, $raw_opts->{$key}{$_} foreach keys %{$raw_opts->{$key}}; print OPTS " },\n\n"; } elsif( ref $raw_opts->{$key} ) { # Something else, probably the cookie jar. Use data dumper. my $dumpedInfo = Dumper( $raw_opts->{$key} ); $dumpedInfo =~ s/\$VAR1 = //; $dumpedInfo =~ s/;$/,/; printf OPTS " '%s' => %s\n", $key, $dumpedInfo, } else { # plain string, number etc. if( defined $raw_opts->{$key} ) { printf OPTS " '%s' => '%s',\n\n", $key, $raw_opts->{$key}; } else { printf OPTS " '%s' => undef,\n\n", $key; } } } print OPTS "};\n\n"; close OPTS; return; }