Developer Forums | About Us | Site Map
Search  
HOME > TUTORIALS > SERVER SIDE CODING > PERL TUTORIALS > THE ROAD TO BETTER PROGRAMMING: CHAPTER 7. TOP LEVEL CONTROL FLOW


Sponsors





Useful Lists

Web Host
site hosted by netplex

Online Manuals

The road to better programming: Chapter 7. Top-level control flow
By Teodor Zlatanov - 2004-03-15 Page:  1 2 3 4 5

Command-line switches and other configuration options

There are many CPAN modules for application configuration. I picked AppConfig because I had experience with it, and because it could mimic the behavior of cfengine's configuration switches.

Each switch is given an alias. For instance, -define and -D are equivalent, which necessitated using -v as the shortcut for -debug. I could have used case sensitivity to distinguish between them as well.

Help (-h) and input (-i) are options without arguments. Debug (-v), fileread (-f, named fileread because AppConfig has an internal file() method), and exec (-e) are one-argument options. Define (-D) is the only list option, so the user can say "-D Alpha -D Beta" and have both Alpha and Beta defined.

I use the AppConfig args() method to read the arguments from @ARGV.

Listing 7. cfperl command-line switches definition

        
my $config = AppConfig->new();
$config->define(
    'HELP'            => { ARGCOUNT => ARGCOUNT_NONE,
               DEFAULT => 0,
               ALIAS => 'h'},

    'DEBUG'           => { ARGCOUNT => ARGCOUNT_ONE,
               DEFAULT => 0,
               ALIAS => 'v'},

    'DEFINE'          => { ARGCOUNT => ARGCOUNT_LIST,
               ALIAS => 'D'},

    'FILEREAD'        => { ARGCOUNT => ARGCOUNT_ONE,
               DEFAULT => 0,
               ALIAS => 'f' },

    'EXEC'            => { ARGCOUNT => ARGCOUNT_ONE,
               DEFAULT => 0,
               ALIAS => 'e' },

    'INPUT'           => { ARGCOUNT => ARGCOUNT_NONE,
               DEFAULT => 0,
               ALIAS => 'i' },
         );

# now read the command-line options from @ARGV
out(0, "main: Invalid options passed, ignoring") unless $config->args();

Things get a little tricky when the main loop begins. We have to process all the command-line switches. First we define all the classes given with the -D option.

Listing 8. cfperl command-line switches processing: the -define option

        
foreach my $class (@{$config->DEFINE})
{
 out(1, "Defining class $class on user request");
 $classes{$class} = 1;
}

Now, the input file is processed. We define $config_file to be a IO::File object (a much more reliable way to process file data than the classic Perl FILE handles, for many reasons). If the -f option specified a readable file, we set $config_file to be that file. Else, if the -i option was given, $config_file is set to be the standard input of cfperl. Else, if the -e option was given, we just process that option's argument, do a quick cfrun() and exit. Finally, if all else failed, we use the GLOBAL_CONFIG_FILE defined in the constants section.

The complex options available to cfperl users mimic the options available with cfengine, but they are not the same options and they shouldn't have to be. cfperl does not aim to replace cfengine, only to add functionality to it. Duplicating all of cfengine's behavior and command-line switches would be both unnecessary and difficult.

Listing 9. cfperl command-line switches processing: the file processing

        
my $config_file = new IO::File;

if (-r $config->FILEREAD)    # we can read the -f argument
{
 $config_file->open('< ' . $config->FILEREAD);
}
elsif ($config->INPUT)     # -i means read configuration interactively
{
 $config_file->fdopen(fileno(STDIN),"r");
}
elsif ($config->EXEC)      # just run the one line
{
 process_line($config->EXEC) && cfrun();
 exit;
}
else          # none of the above, use GLOBAL_CONFIG_FILE
{
 $config_file->open('< ' . GLOBAL_CONFIG_FILE);
}

exit unless $config_file->opened();
# we continue to a parse_line/cfrun loop done on $config_file

Next time, we will finish the code for cfperl -- see you then.



View The road to better programming: Chapter 7. Top-level control flow Discussion

Page:  1 2 3 4 5 Next Page: Resources

First published by IBM developerWorks


Copyright 2004-2017 GrindingGears.com. All rights reserved.
Article copyright and all rights retained by the author.