in reply to [General] Non-Specific Options Question

Update: For a more concrete application of the idea which is not as overdesigned as my approach, see kcott's reply.

I like the following cascade of options, but if you are just starting out with your program, I recommend that you go with the config file alone, or maybe config file + defaults. Here are the overkill steps to do that:

  1. Set up defaults:
    sub get_defaults { return +{ output_type => 'excel', output_dir => '/tmp', ... }; };
  2. Read a config file, maybe JSON or YAML. YAML is supposed to be "user-friendly" (which I think it isn't), but it's commonly used. JSON is a contender but it doesn't allow comments, which I think are important in a config file.
    use YAML 'LoadFile'; sub config_from_file { my( $filename ) = @_; LoadFile( $filename ) }
  3. Use switches from the environment:
    sub config_from_ENV { my ( $env ) = @_; { output_type => $env->{MYAPP_output_type}, ... } }
  4. Use command line switches:
    sub config_from_ARGV { my( $argv ) = @_; GetOptionsFromArray ( 'f|config_file:s' => \my $config_file, 't|output_type:s' => \my $output_type, ); return +{ config_file => $config_file, output_type => $output_type, },
  5. Merge all the values, starting from the default upwards:
    my $defaults = get_defaults(); my $argv = config_from_ARGV( \@ARGV ); my $config_file = $argv->{config_file} || 'myconfig.yml'; my $file = config_from_file( $config_file ); my $env = config_from_ENV( \%ENV ); # Merge the things my $final_config = $defaults; for my $cfg ($config_file, $env, $argv) { for my $entry (keys %$cfg) { if(defined $cfg->{$entry}) { $final_config->{ $entry } = $cfg->{ $entry }; }; }; };
  6. Done

For a start, I would only implement get_defaults and config_from_ARGV, or even skip one of the two.