Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
App::Options(3)	      User Contributed Perl Documentation      App::Options(3)

NAME
       App::Options - Combine command line options, environment	vars, and
       option file values (for program configuration)

SYNOPSIS
	   #!/usr/bin/perl -w
	   use strict;

	   use App::Options;   # reads option values into %App::options	by default

	   # do	something with the options (in %App::options)
	   use DBI;
	   $dsn	= "dbi:mysql:database=$App::options{dbname}";
	   $dbh	= DBI->connect($dsn, $App::options{dbuser}, $App::options{dbpass});
	   ...

	 Get help from the command line	(assuming program is named "prog") ...

	   prog	-?
	   prog	--help

	 Option	values may be provided on the command line, in environment
	 variables, and	option files.  (i.e. $ENV{APP_DBNAME} would set
	 the value of %App::options{dbname} by default.)

	 The "dbname" and other	options	could also be set in one of the
	 following configuration files

	   /etc/app/policy.conf
	   $HOME/.app/prog.conf
	   $HOME/.app/app.conf
	   $PROGDIR/prog.conf
	   $PROGDIR/app.conf
	   $PREFIX/etc/app/prog.conf
	   $PREFIX/etc/app/app.conf
	   /etc/app/app.conf

	 with a	file format like

	   [prog]
	   dbname = prod
	   dbuser = scott
	   dbpass = tiger

	 See below for a more detailed explanation of these and	other
	 advanced features.

DESCRIPTION
       App::Options combines command-line arguments, environment variables,
       option files, and program defaults to produce a hash of option values.

RELATION TO OTHER CONFIGURATION/OPTION PARSING MODULES
       A number	of modules are posted on CPAN which do command-line
       processing.

	http://search.cpan.org/modlist/Option_Parameter_Config_Processing

       App::Options is different than most of the Getopt::* modules because it
       integrates the processing of command line options, environment
       variables, and config files.

       Furthermore, its	special	treatment of the "perlinc" option facilitates
       the inclusion ("use") of	application-specific perl modules from special
       places to enable	the installation of multiple versions of an
       application on the same system (i.e.  /usr/myproduct/version).

       The description of the AppConfig	distribution sounds similar to what is
       described here.	However, the following are some	key differences.

	* App::Options does its	option processing in the BEGIN block.
	  This allows for the @INC variable to be modified in time
	  for subsequent "use" and "require" statements.

	* App::Options "sections" (i.e.	"[cleanup]") are conditional.
	  It is	conditional in App::Options, allowing you to use one
	  set of option	files to configure an entire suite of programs
	  and scripts.	In AppConfig, the section name is simply a
	  prefix which gets prepended to subsequest option names.

	* App::Options consults	a cascading set	of option files.
	  These	files include those which are system global, project
	  global, and user private.  This allows for system
	  administrators, project developers, and individual
	  users	to all have complementary roles	in defining
	  the configuration values.

	* App::Options is not a	toolkit	but a standardized way of
	  doing	option processing.  With AppConfig, you	still have
	  to decide where to put config	files, and you still have to
	  code the "--help" feature.  With App::Options, you simply
	  "use App::Options;" and all the hard work is done.
	  Advanced options can be added	later as necessary as args
	  to the "use App::Options;" statement.

       App::Options is also the	easiest	command-line processing	system that I
       have found anywhere. It then provides a smooth transition to more
       advanced	features only as they are needed.  Every single	quick and
       dirty script I ever write from now on can afford	to use App::Options.

       The documentation of App::Options takes three forms below.

	 API Reference - describing the	API (methods, args)
	 Logic Flow - describing the order and logic of	processing
	 Usage Tutorial	- describing how to use	the API	in practical situations

RELATION TO THE	P5EE PROJECT
       App::Options was	motivated by and supports the P5EE/App-Context variant
       of the Perl 5 Enterprise	Environment (P5EE).  However, App::Options has
       no dependency on	any other module in the	P5EE project, and it is	very
       useful without any knowledge or use of other elements of	the P5EE
       project.

       See the P5EE web	sites for more information on the P5EE project.

	   http://www.officevision.com/pub/p5ee/index.html

API REFERENCE: Methods
   init()
	   * Signature:	App::Options->init();
	   * Signature:	App::Options->init(%named);
	   * Signature:	App::Options->init($myvalues);
	   * Signature:	App::Options->init($myvalues, %named);
	    (NOTE: %named represents a list of name/value pairs	used as	named args.
		   Params listed below without a $ are named args.)
	   * Param:  $myvalues	   HASH
		     specify a hash reference other than %App::options to put
		     configuration values in.
	   * Param:  values	   HASH
		     specify a hash reference other than %App::options to put
		     configuration values in.
	   * Param:  options	   ARRAY
		     specify a limited,	ordered	list of	options	to be displayed
		     when the "--help" or "-?" options are invoked
	   * Param:  option	   HASH
		     specify additional	attributes of any of
		     the various options to the	program	(see below)
	   * Param:  no_cmd_args
		     do	not process command line arguments
	   * Param:  no_env_vars
		     do	not read environment variables
	   * Param:  no_option_file
		     do	not read in the	option file(s)
	   * Param:  print_usage
		     provide an	alternate print_usage()	function
	   * Return: void
	   * Throws: "App::Options->init(): must have an even number of	vars/values for	named args"
	   * Throws: "App::Options->init(): 'values' arg must be a hash	reference"
	   * Throws: "App::Options->init(): 'option' arg must be a hash	reference"
	   * Throws: "App::Options->init(): 'options' arg must be an array reference"
	   * Since:  0.60

	   Sample Usage: (normal)

	   use App::Options;	   # invokes init() automatically via import()

	   This	is functionally	equivalent to the following, but that's	not
	   near	as nice	to write at the	top of your programs.

	   BEGIN {
	       use App::Options	qw(:none); # import() does not call init()
	       App::Options->init();	   # we	call init() manually
	   }

	   Or we could have used a more	full-featured version ...

	   use App::Options (
	       values => \%MyPackage::options,
	       options => [ "option_file", "prefix", "app",
			    "perlinc", "debug_options",	"import", ],
	       option => {
		   option_file	 => { default => "~/.app/app.conf" },	      #	set default
		   app		 => { default => "app",	type =>	"string" }, # default &	type
		   prefix	 => { type => "string",	required => 1; env => "PREFIX" },
		   perlinc	 => undef,	   # no	default
		   debug_options => { type => "int" },
		   import	 => { type => "string" },
		   flush_imports => 1,
	       },
	       no_cmd_args => 1,
	       no_env_vars => 1,
	       no_option_file => 1,
	       print_usage => sub { my ($values, $init_args) = @_; print "Use it right!\n"; },
	   );

       The init() method is usually called during the import() operation when
       the normal usage	("use App::Options;") is invoked.

       The init() method reads the command line	args (@ARGV), then finds an
       options file, and loads it, all in a way	which can be done in a BEGIN
       block (minimal dependencies).  This is important	to be able to modify
       the @INC	array so that normal "use" and "require" statements will work
       with the	configured @INC	path.

       The following named arguments are understood by the init() method.

	   values - specify a hash reference other than	%App::options to
		    put	option values in.
	   options - specify a limited,	ordered	list of	options	to be
		     displayed when the	"--help" or "-?" options are invoked
	   option - specify optional additional	information about any of
		    the	various	options	to the program (see below)
	   no_cmd_args - do not	process	command	line arguments
	   no_env_vars - do not	read environment variables
	   no_option_file - do not read	in the option file
	   show_all - force showing all	options	in "--help" even when
		    "options" list specified
	   print_usage - provide an alternate print_usage() function
	   args_description - provide descriptive text for what	the args
		    of the program are (command	line args after	the options).
		    This is printed in the usage page (--help or -?).
		    By default,	it is simply "[args]".

       The additional information that can be specified	about any individual
       option variable using the "option" arg above is as follows.

	   default - the default value if none supplied	on the command
	       line, in	an environment variable, or in an option file
	   required - the program will not run unless a	value is provided
	       for this	option
	   type	- if a value is	provided, the program will not run unless
	       the value matches the type ("string", "integer",	"float",
	       "boolean", "date", "time", "datetime", "/regexp/").
	   env - a list	of semicolon-separated environment variable names
	       to be used to find the value instead of "APP_{VARNAME}".
	   description - printed next to the option in the "usage" page
	   secure - identifies an option as being "secure" (i.e. a password)
	       and that	it should never	be printed in plain text in a help
	       message (-?).  All options which	end in "pass", "passwd", or
	       "password" are also assumed to be secure	unless a secure	=> 0
	       setting exists. If the value of the "secure" attribute is greater
	       than 1, a heightened security level is enforced:	2=ensure that
	       the value can never be supplied on a command line or from the
	       environment but only from a file	that only the user running the
	       program has read/write access to.  This value will also never be
	       read from the environment or the	command	line because these are
	       visible to other	users.	If the security_policy_level variable
	       is set, any true	value for the "secure" attribute will result in
	       the value being set to the "security_policy_level" value.
	   value_description - printed within angle brackets ("<>") in the
	       "usage" page as the description of the option value
	       (i.e. --option_name=<value_description>)

       The init() method stores	command	line options and option	file values
       all in the global %App::options hash (unless the	"values" argument
       specifies another reference to a	hash to	use).

       The special options are as follows.

	   option_file - specifies the exact file name of the option file to be
	      used (i.e. "app --option_file=/path/to/app.conf").

	   app - specifies the tag that	will be	used when searching for
	      an option	file. (i.e. "app --app=myapp" will search for "myapp.conf"
	      before it	searches for "app.conf")
	      "app" is automatically set with the stem of the program file that
	      was run (or the first part of PATH_INFO) if it is	not supplied at
	      the outset as an argument.

	   prefix - This represents the	base directory of the software
	      installation (i.e. "/usr/myproduct/1.3.12").  If it is not
	      set explicitly, it is detected from the following	places:
		 1. PREFIX environment variable
		 2. the	real path of the program with /bin or /cgi-bin stripped
		 3. /usr/local (or whatever "prefix" perl was compiled with)
	      If it is autodetected from one of	those three places, that is
	      only provisional,	in order to find the "option_file".  The "prefix"
	      variable should be set authoritatively in	the "option_file" if it
	      is desired to be in the $values structure.

	   perlinc - a path of directories to prepend to the @INC search path.
	      This list	of directories is separated by any combination of
	      [,; ] characters.

	   debug_options - if this is set, a variety of	debug information is
	      printed out during the option processing.	 This helps in debugging
	      which option files are being used	and what the resulting variable
	      values are.  The following numeric values	are defined.

		 1 = print the basic steps of option processing
		 2 = print each	option file searched, final values, and	resulting @INC
		 3 = print each	value as it is set in the option hash
		 4 = print overrides from ENV and variable substitutions
		 5 = print each	line of	each file with exclude_section indicator
		 6 = print option file section tags, condition evaluation, and
		     each value	found (even if it is not set in	the final values)
		 7 = print final values

	   import - a list of additional option	files to be processed.
	      An imported file goes on the head	of the queue of	files to be
	      processed.

	   hostname - the hostname as returned by the hostname() function
	      provided by Sys::Hostname	(may or	may not	include	domain
	      qualifiers as a fully qualified domain name).

	   host	- same as hostname, but	with any trailing domain name removed.
	      (everything after	the first ".")

	   flush_imports - flush all pending imported option files.

	   security_policy_level - When	set, this enforces that	whenever secure
	      attributes are applied, they are set to the same level. When set
	      0, all of	the security features are disabled (passwords can be
	      viewed with "--security_policy_level=0 --help").	When set to 2,
	      all secure options can only be read from files which do not have
	      read/write permission by any other user except the one running the
	      program.

LOGIC FLOW: OPTION PROCESSING DETAILS
       Basic Concept - By calling App::Options->init(),	your program parses
       the command line, environment variables,	and option files, and puts
       var/value pairs into a global option hash, %App::options.  Just include
       the following at	the top	of your	program	in order to imbue it with many
       valuable	option-setting capabilities.

	   use App::Options;

       When you	"use" the App::Options module, the import() method is called
       automatically.  This calls the init() method, passing along all of its
       parameters.

       One of the args to init() is the	"values" arg, which allows for a
       different hash to be specified as the target of all option variables
       and values.

	   use App::Options (values => \%Mymodule::opts);

       Throughout the following	description of option processing, the
       %App::options hash may be referred to as	the "options hash".  However
       it will be understood that some other hash (as specified	by the
       "values"	arg) may actually be used.

   Command Line	Arguments
       Unless the "no_cmd_args"	arg is specified to init(), the	first source
       of option values	is the command line.

       Each command line argument that begins with a "-" or a "--" is
       considered to be	an option.  It may take	any form such as

	   --verbose	  # long option, no arg
	   --verbose=5	  # long option, with arg
	   --city=ATL	  # long option, with arg
	   -x		  # short option, no arg
	   -t=12:30	  # short option, with arg

       All detected options are	shifted	out of @ARGV and the values are	set in
       the options hash	(%App::options).  Options without args are understood
       to have a value of "1".	So "--verbose" is identical to "--verbose=1".

       Naturally, the "--" option terminates command line option processing.

   Command Line	Argument Variable Substitution
       Any value which includes	a variable undergoes variable substitution
       before it is placed in the option hash. i.e.

	   logdir = ${prefix}/log

       This line will be expanded properly.  (Of course, the variable and its
       value should be already set in the option hash.)

       Variable	substitution is	also performed to interpolate values from the
       environment.

	   port	= $ENV{HTTP_PORT}

   Special Option "app"
       If the special option, "app", was not given on the command line,	it is
       initialized.  This option is useful for including or excluding
       different sections of the option	files.

       To handle the special case that the program is running in a CGI
       environment, the	PATH_INFO variable is checked first.  The first
       segment of the PATH_INFO	is stripped off, and that becomes the value of
       the "app" option.

       Otherwise, the stem of the program name becomes the value of the	"app"
       option.	The stem is the	program	name without any trailing extension
       (i.e. ".exe", ".pl", etc.).

   The Program Directory
       One of the places that will be searched for option files	is the
       directory in which the program exists on	the file system.  This
       directory is known internally as	"$prog_dir".

   Special Option "prefix"
       The special option, "prefix", represents	the root directory of the
       software	installation.  On a Unix system, a suite of software might by
       installed at "/usr/myproduct/thisversion", and that would be the
       "prefix".  Under	this directory,	you would expect to find the "src",
       "bin", "lib", and "etc" directories, as well as perhaps "cgi-bin",
       "htdocs", and others.

       If the "prefix" option is not specified on the command line, the
       $PREFIX environment variable is used.

       If that is not set, the $prog_dir with the trailing "/bin" or
       "/cgi-bin" stripped off is used.

   Option Files
       Unless the "no_option_file" arg is specified to init(), the next	source
       of option values	is the option files.

       By default, a cascading set of option files are all consulted to	allow
       individual users	to specify values that override	the normal values for
       certain programs.  Furthermore, the values for individual programs can
       override	the values configured generally	system-wide.

       The resulting value for an option variable comes	from the first place
       that it is ever seen.  Subsequent mentions of the option	variable
       within the same or other	option files will be ignored.

       The following files are consulted in order.

	   $ENV{HOME}/.app/$app.conf
	   $ENV{HOME}/.app/app.conf
	   $prog_dir/$app.conf
	   $prog_dir/app.conf
	   $prefix/etc/app/$app.conf
	   $prefix/etc/app/app.conf
	   /etc/app/app.conf

       Thus, a system administrator might set up the $prefix/etc/app/app.conf
       file with system-wide defaults.	All option configuration could be done
       in this single file, separating the relevant variables into different
       sections	for each different program to be configured.

       However,	if the administrator decided that there	were too many
       parameters for a	single program such that it cluttered this file, he
       might put the option values for that program into the
       $prefix/etc/app/$app.conf file.	This distinction is a matter of
       preference, as both methods are equally functional.

       A program developer may decide to override some of the system-wide
       option values for everyone by putting option files in the program's own
       directory.

       Furthermore, a user may decide to override some of the resulting	option
       values by putting some option files in the appropriate place under his
       home directory.

       This separation of config files also allows for secure information
       (such as	database passwords) to be required to be provided in the
       user's own (secured) option files rather	than in	read-only system-wide
       option files.

       Specifying the "--debug_options"	option on the command line will	assist
       in figuring out which files App::Options	is looking at.

   Option File Format
       In general an option file takes the form	of lines with "var = value".

	  dbname   = prod     #	this is	the production database
	  dbuser   = scott
	  dbpass   = tiger

       Trailing	comments (preceded by a	"#") are trimmed off.  Spaces before
       and after the variable, and before and after the	value are all trimmed
       off.  Then enclosing double-quotes (") are trimmed off.	Variables can
       be any of the characters	in [a-zA-Z0-9_.-].  Values can be any
       printable characters or the empty string.  Any lines which aren't
       recognizable as "var = value" lines or section headers (see below) are
       ignored.

       If certain variables should be set only for certain programs (or	under
       certain other conditions), section headers may be introduced.  The
       special section headers "[ALL]" and "[]"	specify	the end	of a
       conditional section and the resumption of unconditional option
       variables.

	  [progtest]
	  dbname   = test     #	this is	the test database
	  [ALL]
	  dbname   = prod     #	this is	the production database
	  dbuser   = scott
	  dbpass   = tiger

       In this case, the "progtest" program will get "dbname = test" while all
       other programs will get "dbname = prod".

       Note that you would not get the desired results if the "dbname =	prod"
       statement was above the "[progtest]" header.  Once an option variable
       is set, no other	occurrence of that variable in any option file will
       override	it.

       For the special case where you want to specify a	section	for only one
       variable	as above, the following	shortcut is provided.

	  [progtest] dbname = test # this is the test database
	  dbname   = prod	   # this is the production database
	  dbuser   = scott
	  dbpass   = tiger

       The "[progtest]"	section	header applied for only	the single line.

       Furthermore, if it were desired to make this override for all programs
       containing "test" in them, you would use	the following syntax.

	  [/test/] dbname = test   # this is the test database
	  dbname   = prod	   # this is the production database
	  dbuser   = scott
	  dbpass   = tiger

       The "[/test/]" section header tested the	"app" option using an
       arbitrary regular expression.

       The section headers can create a	condition for inclusion	based on any
       of the variables	currently in the option	hash.  In fact,	"[progtest]"
       is just a synonym for "[app=progtest]" and "[/test/]" is	a synonym for
       "[app=/test/]".

       If, for instance, the usernames and passwords were different for	the
       different databases, you	might have the following.

	  [/test/] dbname = test   # progs with	"test" go to test database
	  dbname   = prod	   # other progs go to the production database
	  [dbname=test]		   # progs
	  dbuser   = scott
	  dbpass   = tiger
	  [dbname=prod]
	  dbuser   = mike
	  dbpass   = leopard

       The conditions created by a section header may be the result of more
       than a single condition.

	  [dbname=test;dbuser=scott]
	  dbpass = tiger
	  [dbname=test;dbuser=ken]
	  dbpass = ocelot
	  [dbname=prod;dbuser=scott]
	  dbpass = tiger62
	  [dbname=prod;dbuser=ken]
	  dbpass = 3.ocelot_

       Any number of conditions	can be included	with semicolons	separating
       them.

       Each time a variable/value pair is found	in an option file, it is only
       included	in the option hash if that variable is currently not defined
       in the option hash.  Therefore, option files never override command
       line parameters.

   Option Environment Variables	and Variable Substitution
       For each	variable/value pair that is to be inserted into	the option
       hash from the option files, the corresponding environment variables are
       searched	to see if they are defined.  The environment always overrides
       an option file value.  (If the "no_env_vars" arg	was given to the
       init() method, this whole step of checking the environment is skipped.)

       By default, the environment variable for	an option variable named
       "dbuser"	would be "APP_DBUSER".	However, if the	"env" attribute	of the
       "dbuser"	option is set, a different environment variable	may be checked
       instead (see the	Tutorial below for examples).

       After checking the environment for override values, any value which
       includes	a variable undergoes variable substitution before it is	placed
       in the option hash.

   Setting Environment Variables from Option Files
       Any variable of the form	"ENV{XYZ}" will	set the	variable XYZ in	the
       environment rather than in the options hash.  Thus, the syntax

	 ENV{LD_LIBRARY_PATH} =	${prefix}/lib

       will enhance the	LD_LIBRARY_PATH	appropriately.

       Note that this only works for options set in an options file.  It does
       not work	for options set	on the command line, from the environment
       itself, or from the program-supplied default.

       Under some circumstances, the perl interpreter will need	to be
       restarted in order to pick up the new LD_LIBRARY_PATH.  In that case,
       you can include the special option

	 perl_restart =	1

       An example of where this	might be useful	is for CGI scripts that	use
       the DBI and DBD::Oracle because the Oracle libraries are	dynamically
       linked at runtime.

       NOTE: The other standard	way to handle CGI scripts which	require
       special environment variables to	be set is with Apache directives in
       the httpd.conf or .htaccess files. i.e.

	 SetEnv	LD_LIBRARY_PATH	/home/oracle/oracle/product/10.2.0/oraclient/lib
	 SetEnv	ORACLE_HOME /home/oracle/oracle/product/10.2.0/oraclient

       NOTE: Yet another standard way to handle	CGI scripts which require an
       enhanced	LD_LIBRARY_PATH	specifically is	to use the /etc/ld.so.conf
       file.  Edit /etc/ld.so.conf and then run	ldconfig (as root).  This adds
       your specific path to the "standard system places" that are searched
       for shared libraries.  This has nothing to do with App::Options or
       environment variables of	course.

   import and flush_imports
       After each option file is read, the special option "flush_imports" is
       checked.	 If set, the list of pending option files to be	parsed is
       cleared,	and the	flush_imports option is	also cleared.

       This is useful if you do	not want to inherit any	of the option values
       defined in system-wide option files.

       The special option "import" is checked next.  If	it is set, it is
       understood to be	a list of option files (separated by /[,; ]+/) to be
       prepended to the	list of	pending	option files.  The import option
       itself is cleared.

   Other Environment Variables and Defaults
       After command line options and option files have	been parsed, all of
       the other options which are known to the	program	are checked for
       environment variables and defaults.

       Options can be defined for the program with either the "options"	arg or
       the "option" arg	to the init() method (or a combination of both).

	   use App::Options (
	       options => [ "dbname", "dbuser",	"dbpass" ],
	       option => {
		   dbname => {
		       env => "DBNAME",
		       default => "devel",
		   },
		   dbuser => {
		       env => "DBUSER;DBI_USER",
		   },
		   dbpass => {
		       env => "", # password in	%ENV is	security breach
		   },
	       },
	   );

       For each	option variable	known, if the value is not already set,	then
       the environment is checked, the default is checked, variable expansion
       is performed, and the value is entered into the option hash.

   Special Option prefix
       The special option "prefix" is reconciled and finalized next.

       Unless it was specified on the command line, the	original "prefix" was
       autodetected.  This may have resulted in	a path which was technically
       correct but was different than intended due to symbolic linking on the
       file system.

       Since the "prefix" variable may also be set in an option	file, there
       may be a	difference between the auto-detected "prefix" and the option
       file "prefix".  If this case occurs, the	option file "prefix" is	the
       one that	is accepted as authoritative.

   Special Option perlinc
       One of the primary design goals of App::Options was to be able to
       support multiple	installations of software on a single machine.

       Thus, you might have different versions of software installed under
       various directories such	as

	   /usr/product1/1.0.0
	   /usr/product1/1.1.0
	   /usr/product1/2.1.5

       Naturally, slightly different versions of your perl modules will	be
       installed under each different "prefix" directory.  When	a program runs
       from /usr/product1/1.1.0/bin, the "prefix" will by
       "/usr/product1/1.1.0" and we want the @INC variable to be modified so
       that the	appropriate perl modules are included from $prefix/lib/*.

       This is where the "perlinc" option comes	in.

       If "perlinc" is set, it is understood to	be a list of paths (separated
       by /[ ,;]+/) to be prepended to the @INC	variable.

       If "perlinc" is not set,	"$prefix/lib/perl5/$perlversion" and
       "$prefix/lib/perl5/site_perl/$perlversion" are automatically prepended
       to the @INC variable as a best guess.

   Special Option debug_options
       If the "debug_options" variable is set (often on	the command line), the
       list of option files that was searched is printed out, the resulting
       list of variable	values is printed out, and the resulting list of
       include directories (@INC) is printed out.

   Version
       After all values	have been parsed, various conditions are checked to
       see if the program should print diagnostic information rather than
       continue	running.  Two of these examples	are --version and --help.

       If the "--version" option is set	on the command line, the version
       information for all loaded modules is printed, and the program is
       exited.	(The version of	a package/module is assumed to be the value of
       the $VERSION variable in	that package.  i.e. The	version	of the
       XYZ::Foo	package	is $XYZ::Foo::VERSION.)

	prog --version

       Of course, this is all done implicitly in the BEGIN block (during "use
       App::Options;").	 If your program tried to set $main::VERSION, it may
       not be set unless it is set explicitly in the BEGIN block.

	#!/usr/bin/perl
	BEGIN {
	  $VERSION = "1.12";
	}
	use App::Options;

       This can	be integrated with CVS file versioning using something like
       the following.

	#!/usr/bin/perl
	BEGIN {
	  $VERSION = do	{ my @r=(q$Revision: 14478 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r};
	}
	use App::Options;

       Furthermore, the	version	information about some modules that you	might
       expect to have seen will	not be printed because those modules have not
       yet been	loaded.	 To fix	this, use the --version_packages option	(or
       set it in an option file).  This	option contains	a comma-separated list
       of modules and/or module	regular	expressions.  The modules are loaded,
       and the version information from	all resulting packages that match any
       of the patterns is printed.

	prog --version --version_packages=CGI
	prog --version --version_packages=CGI,Template

       This also cuts down on the miscellaneous	modules	(and pragmas) which
       might have cluttered up your view of the	version	information you	were
       interested in.  If you really wish to see version information for all
       modules,	use the	--version=all option.

	prog --version=all --version_packages=CGI,Template

   Help	and Validations
       If the "-?" or "--help" options were set	on the command line, the usage
       statement is printed, and the program is	exited.

       Then each of the	options	which is defined may be	validated.

       If an option is designated as "required", its value must	be defined
       somewhere (although it may be the empty string).	 (If it	is also
       required	to be a	non-empty string, a regex may be provided for the
       type, i.e. type => "/./".)

       If an option is designated as having a "type", its value	must either be
       undefined or match a specific regular expression.

	   Type	      Regular Expression
	   =========  =========================================
	   string     (any)
	   integer    /^-?[0-9_]+$/
	   float      /^-?[0-9_]+\.?[0-9_]*([eE][+-]?[0-9_]+)?$/
		 (or) /^-?\.[0-9_]+([eE][+-]?[0-9_]+)?$/
	   boolean    /^[01]$/
	   date	      /^[0-9]{4}-[01][0-9]-[0-3][0-9]$/
	   datetime   /^[0-9]{4}-[01][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]$/
	   time	      /^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]$/
	   /regexp/   /regexp/

       Note that an arbitrary regular expression may be	designated as the
       "type" by enclosing it in slashes (i.e. "/^[YN]$/").

       If the options fail any of the "required" or "type" validation tests,
       the App::Options::print_usage() function	is called to print out a usage
       statement and the program is exited.

USAGE TUTORIAL
   Getting Started
       Create a	perl program called "demo1".

	   #!/usr/bin/perl
	   use App::Options;
	   print "Wow. Here are	the options...\n";
	   foreach (sort keys %App::options) {	# options appear here!
	       printf("%-20s =>	%s\n", $_, $App::options{$_});
	   }

       Run it different	kinds of ways to see how it responds.

	   demo1
	   demo1 -x
	   demo1 -x --verbose
	   demo1 --x -verbose
	   demo1 -x=5 --verbose=10 --foo=bar
	   demo1 --help
	   demo1 -x=8 --help
	   demo1 -?
	   demo1 --debug_options -?
	   demo1 -x=5 --verbose=10 --foo=bar --debug_options -?

	   demo1 --version
	   demo1 --version --version_packages=CGI

       Now create a copy of the	program.

	   cp demo1 demo2

       Start putting entries like the following

	   x = 7
	   hello = world
	   [demo2]
	   verbose=3
	   [/demo/]
	   baz = foo

       in the following	files

	   $HOME/.app/demo1.conf
	   $HOME/.app/demo2.conf
	   $HOME/.app/app.conf
	   demo1.conf  (same directory as the demo* programs)
	   demo2.conf  (same directory as the demo* programs)
	   app.conf    (same directory as the demo* programs)
	   $PREFIX/etc/app/demo1.conf
	   $PREFIX/etc/app/demo2.conf
	   $PREFIX/etc/app/app.conf
	   /etc/app/app.conf

       and see how the programs	respond	in each	different case.

       Next set	environment variables like the following and see how the
       programs	respond.

	   export APP_X=14
	   export APP_VERBOSE=7
	   export APP_FOO=xyzzy
	   export APP_HELLO=Plugh!

       You are well on your way.

   A Development Scenario
       Now let's imagine that we are writing a suite of	programs which operate
       on a relational database.  These	programs are part of a larger system
       which goes through a development	cycle of development, test, and
       production.  Each step in the development cycle,	the programs will run
       against different databases, but	we don't want that to affect the code.

       Let's suppose that we write a program which lists the customers in a
       customer	table.

	   create table	person (
	       person_id      integer	    not	null auto_increment primary key,
	       first_name     varchar(99)   null,
	       last_name      varchar(99)   null,
	       birth_dt	      date	    null,
	       company_id     integer	    null,
	       wholesale_ind  char(1)	    null,
	       change_dttm    datetime	    not	null,
	   );

       We call this program "listcust".

	   #!/usr/bin/perl -e
	   use strict;
	   use App::Options;
	   use DBI;
	   my $dsn = "dbi:$App::options{dbdriver}:database=$App::options{dbname}";
	   my $dbh = DBI->connect($dsn,	$App::options{dbuser}, $App::options{dbpass});
	   my $sql = "select first_name, last_name, birth_dt, company_id, wholesale_ind, change_dttm from person";
	   my $cust = $dbh->selectall_arrayref($sql);
	   foreach my $row (@$cust) {
	       printf("%-24 %-24 %s %9d	%s\n", @$row);
	   }
	   $dbh->disconnect();

       Then you	can invoke this	program	with all of the	command	line options
       and everything works fine.

	   listcust --dbdriver=mysql --dbname=prod --dbuser=scott --dbpass=tiger

       However,	if you don't use all of	the options, you will get a DBI	error.
       Furthermore, "listcust --help" doesn't help very	much.  A system
       administrator confronting this problem would put	the following lines
       into "$PREFIX/etc/app/app.conf" or "$PREFIX/etc/app/listcust.conf".

	   dbdriver = mysql
	   dbname   = prod
	   dbuser   = scott
	   dbpass   = tiger

       If, however, your projects were not in the habit	of using the PREFIX
       environment variable and	the program is not installed in	$PREFIX/bin,
       he would	have to	put the	above lines in either the "app.conf" file or
       the "listcust.conf" file	in the same directory as "listcust" or in the
       global "/etc/app/app.conf" option file.

       A user (without privileges to the "$PREFIX/etc/app" directory or	the
       directory in which "listcust" lives) would have to put the described
       lines into "$HOME/.app/app.conf"	or "$HOME/.app/listcust.conf".

       Putting the options in any of those files would make "--help" print
       something intelligent.

       A developer, however, might decide that the program should have some
       defaults.

	   use App::Options (
	       option => {
		   dbdriver => "mysql",
		   dbname   => "prod",
		   dbuser   => "scott",
		   dbpass   => "tiger",
	       },
	   );

       (This supplies defaults and also	makes "--help" print something
       intelligent, regardless of whether there	are any	configuration files.)

       If all you wanted to do was provide defaults for	options, this format
       would be	fine.  However,	there are other	useful attributes of an	option
       besides just the	"default".  To use those, you generally	would use the
       more complete form of the "option" arg.

	   use App::Options (
	       option => {
		   dbdriver => { default => "mysql", },
		   dbname   => { default => "prod",  },
		   dbuser   => { default => "scott", },
		   dbpass   => { default => "tiger", },
	       },
	   );

       Then we can indicate that these options are all required.  If they are
       not provided, the program will not run.

       Meanwhile, it makes no sense to provide a "default" for a password.  We
       can remove the default, but if we ever tried to run the program without
       providing the password, it would	not get	past printing a	"usage"
       statement.

	   use App::Options (
	       option => {
		   dbdriver => { required => 1,	default	=> "mysql", },
		   dbname   => { required => 1,	default	=> "prod",  },
		   dbuser   => { required => 1,	default	=> "scott", },
		   dbpass   => { required => 1,	},
	       },
	   );

       We now might enhance the	code in	order to list only the customers which
       had certain attributes.

	   my $sql = "select first_name, last_name, birth_dt, company_id, wholesale_ind, change_dttm from person";
	   my (@where);
	   push(@where,	"first_name like '%$App::options{first_name}%'")
	       if ($App::options{first_name});
	   push(@where,	"last_name like	'%$App::options{last_name}%'")
	       if ($App::options{last_name});
	   push(@where,	"birth_dt = '$App::options{birth_dt}'")
	       if ($App::options{birth_dt});
	   push(@where,	"company_id = $App::options{company_id}")
	       if ($App::options{company_id});
	   push(@where,	"wholesale_ind = '$App::options{wholesale_ind}'")
	       if ($App::options{wholesale_ind});
	   push(@where,	"change_dttm >=	'$App::options{change_dttm}'")
	       if ($App::options{change_dttm});
	   if ($#where > -1) {
	       $sql .= "\nwhere	" . join("\n  and ", @where) . "\n";
	   }
	   my $cust = $dbh->selectall_arrayref($sql);

       The init() method call might be enhanced	to look	like this.  Also, the
       order that the options are printed by "--help" can be set with the
       "options" argument.  (Otherwise,	they would print in alphabetical
       order.)

	   use App::Options (
	       options => [ "dbdriver",	"dbname", "dbuser", "dbpass",
		   "first_name", "last_name", "birth_dt", "company_id",
		   "wholesale_ind", "change_dttm",
	       ],
	       option => {
		   dbdriver => {
		       description => "dbi driver name",
		       default => "mysql",
		       env => "DBDRIVER",  # use a different env variable
		       required	=> 1,
		   },
		   dbname   => {
		       description => "database	name",
		       default => "prod",
		       env => "DBNAME",	 # use a different env variable
		       required	=> 1,
		   },
		   dbuser   => {
		       description => "database	user",
		       default => "scott",
		       env => "DBUSER;DBI_USER",  # check both
		       required	=> 1,
		   },
		   dbpass   => {
		       description => "database	password",
		       env => "",  # disable env for password (insecure)
		       required	=> 1,
		       secure => 1,   #	FYI. This is inferred by the fact that "dbpass"
				      #	ends in	"pass",	so it is not necessary.
		   },
		   first_name => {
		       description => "portion of customer's first name",
		   },
		   last_name  => {
		       description => "portion of customer's last name",
		   },
		   birth_dt   => {
		       description => "customer's birth	date",
		       type => "date",
		   },
		   company_id => {
		       description => "customer's company ID",
		       type => "integer",
		   },
		   wholesale_ind => {
		       description => "indicator of wholesale customer",
		       type => "/^[YN]$/",
		   },
		   change_dttm => {
		       description => "changed-since date/time",
		       type => "datetime",
		   },
	       },
	   );

       It should be noted in the example above that the	default	environment
       variable	name ("APP_${varname}")	has been overridden for	some of	the
       options.	 The "dbname" variable will be set from	"DBNAME" instead of
       "APP_DBNAME".  The "dbuser" variable will be set	from either "DBUSER"
       or "DBI_USER".

       It should also be noted that if only the	order of the options rather
       than all	of their attributes were desired, the following	could have
       been used.

	   use App::Options (
	       options => [ "dbdriver",	"dbname", "dbuser", "dbpass",
		   "first_name", "last_name", "birth_dt", "company_id",
		   "wholesale_ind", "change_dttm",
	       ],
	   );

       Using the "options" arg causes the options to be	printed	in the order
       given in	the "--help" output.  Then the remaining options defined in
       the "option" arg	are printed in alphabetical order.  All	other options
       which are set on	the command line or in option files are	printed	if the
       "show_all" option is set.  This option is off by	default	if either the
       "options" arg or	the "option" arg are supplied and on if	neither	are
       supplied.

       If, for some reason, the	program	needed to put the options into a
       different option	hash (instead of %App::options)	or directly specify
       the option file to use (disregarding the	standard option	file search
       path), it may do	so using the following syntax.

	   use App::Options (
	       values => \%Mymodule::opts,
	       option_file => "/path/to/options.conf",
	   );

       If, for some reason, the	program	needs to inhibit one or	more of	the
       sources for options, it can do so with one of the following arguments.
       Of course, inhibiting all three would be	a bit silly.

	   use App::Options (
	       no_cmd_args => 1,
	       no_option_file => 1,
	       no_env_vars => 1,
	   );

   A Deployment	Scenario
       Sometimes a software system gets	deployed across	many machines.	You
       may wish	to have	a single option	file set different values when it is
       deployed	to different machines.

       For this	purpose, the automatic "host" and "hostname" values are
       useful.	Suppose	you have four servers named "foo1", "foo2", "foo3",
       and "foo4".  You	may wish the software to use different databases on
       each server.  So	app.conf might look like this.

	   [host=foo1] dbname =	devel
	   [host=foo2]
	   dbname = test
	   [host=foo3]
	   dbname = prod
	   [ALL]
	   dbname = prod

       Hopefully, that's enough	to get you going.

       I welcome all feedback, bug reports, and	feature	requests.

ACKNOWLEDGEMENTS
	* (c) 2010 Stephen Adkins
	* Author:  Stephen Adkins <spadkins@gmail.com>
	* License: This	is free	software. It is	licensed under the same	terms as Perl itself.

SEE ALSO
perl v5.32.0			  2010-10-12		       App::Options(3)

NAME | SYNOPSIS | DESCRIPTION | RELATION TO OTHER CONFIGURATION/OPTION PARSING MODULES | RELATION TO THE P5EE PROJECT | API REFERENCE: Methods | LOGIC FLOW: OPTION PROCESSING DETAILS | USAGE TUTORIAL | ACKNOWLEDGEMENTS | SEE ALSO

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=App::Options&sektion=3&manpath=FreeBSD+12.1-RELEASE+and+Ports>

home | help