App-Framework

 view release on metacpan or  search on metacpan

lib/App/Framework/Feature/Options.pm  view on Meta::CPAN


=over 4

=item s

String. An arbitrary sequence of characters. It is valid for the
argument to start with C<-> or C<-->.

=item i

Integer. An optional leading plus or minus sign, followed by a
sequence of digits.

=item o

Extended integer, Perl style. This can be either an optional leading
plus or minus sign, followed by a sequence of digits, or an octal
string (a zero, optionally followed by '0', '1', .. '7'), or a
hexadecimal string (C<0x> followed by '0' .. '9', 'a' .. 'f', case
insensitive), or a binary string (C<0b> followed by a series of '0'
and '1').

=item f

Real number. For example C<3.14>, C<-6.23E24> and so on.

=back

The I<desttype> can be C<@> or C<%> to specify that the option is
list or a hash valued. This is only needed when the destination for
the option value is not otherwise specified. It should be omitted when
not needed.

The I<flag>, if used, can be C<dev:> to specify that the option is meant for application developer
use only. In this case, the option will not be shown in the normal help and man pages, but will
only be shown when the -man-dev option is used.

=head3 summary

The summary is a simple line of text used to summarise the option. It is used in the man pages in 'usage' mode.

=head3 default

Defaults values are optional. If they are defined, they are in the format:

    [default=<value>]

When a default is defined, if the user does not specify a value for an option then that option takes on the defualt value.

=head3 description

The summary is multiple lines of text used to fully describe the option. It is used in the man pages in 'man' mode.

=head2 Variable Expansion

Option values and default values can contain variables, defined using the standard Perl format:

	$<name>
	${<name>}

When the option is used, the variable is expanded and replaced with a suitable value. The value will be looked up from a variety of possible sources:
object fields (where the variable name matches the field name) or environment variables.

The variable name is looked up in the following order, the first value found with a matching name is used:

=over 4

=item *

Option names - the values of any other options may be used as variables in options

=item *

Application fields - any fields of the $app object may be used as variables

=item *

Environment variables - if no application fields match the variable name, then the environment variables are used

=back 

=head2 Script Usage

The application framework passes a reference to the options HASH as the second parameter to the application subroutine B<app>. Alternatively,
the script can call the app object's alias to the options accessor, i.e. the B<options> method which returns the options hash. Yet another
alternative is to call the options accessor method directly. These alternatives are shown below:


    sub app
    {
        my ($app, $opts_href, $args_href) = @_ ;
        
        # use parameter
        my $log = $opts_href->{log}
        
        # access alias
        my %options = $app->options() ;
        $log = $options{log} ;
        
        # access alias
        %options = $app->Options() ;
        $log = $options{log} ;
        
        # feature object
        %options = $app->feature('Options')->options() ;
        $log = $options{log} ;
    }



=head2 Examples

With the following script definition:

    [OPTIONS]
    
    -n|'name'=s        Test name [default=a name]
    
    String option, accessed as $opts_href->{name}. 
    
    -nomacro    Do not create test macro calls

lib/App/Framework/Feature/Options.pm  view on Meta::CPAN

	
	my @combined_options = (@{$this->user_options}) ;
	foreach my $opt_aref (@$options_aref)
	{
		my @opt = ($opt_aref->[0], $opt_aref->[1], $opt_aref->[2], $opt_aref->[3], $caller_pkg) ;
		push @combined_options, \@opt ;
	}
	$this->user_options(\@combined_options) ;

$this->_dbg_prt( ["Options: append_options() new=", $options_aref] , 2) ;
$this->_dbg_prt( ["combined=", \@combined_options] , 2) ;

	## Build new set of options
	$this->update() ;
	
	return @combined_options ;
}

#----------------------------------------------------------------------------

=item B<clear_options()>

Clears the current options list.

=cut

sub clear_options
{
	my $this = shift ;

$this->_dbg_prt( ["Options: clear_options()\n"] ) ;

	$this->user_options([]) ;

}

#----------------------------------------------------------------------------

=item B<get_options()>

Use Getopt::Long to process the command line options. Returns 1 on success; 0 otherwise

=cut

sub get_options
{
	my $this = shift ;

	# Do final processing of the options
	$this->update() ;
	
	# get the list suitable for GetOpts
	my $get_options_aref = $this->_get_options() ;

$this->_dbg_prt( ["get_options() : ARGV=", \@ARGV, " Options=", $get_options_aref], 2 ) ;

	# Parse options using GetOpts
	my $ok = GetOptions(@$get_options_aref) ;

	# Expand the options variables
	$this->_expand_options() ;

$this->_dbg_prt( ["get_options() : ok=$ok  Options now=", $get_options_aref], 2 ) ;

	return $ok ;
}

#----------------------------------------------------------------------------

=item B<option_entry($option_name)>

Returns the HASH ref of option if name is found; undef otherwise.

The HASH ref contains:

	'field' => option 'main' name 
	'spec' => specification string
	'summary' => summary text 
	'description' => description text
	'default' => default value (if specified)
	'pod_spec' => specification string suitable for pod output
	'type' => option type (e.g. s, f etc)
	'dest_type' => destination type (e.g. @, %)
	'developer' => developer only option (flag set if option is to be used for developer use only)
	'entry' => reference to the ARRAY that defined the option (as per L</append_options>) 

=cut

sub option_entry
{
	my $this = shift ;
	my ($option_name) = @_ ;

	my $option_fields_href = $this->_option_fields_hash() ;
	my $opt_href ;
	if (exists($option_fields_href->{$option_name}))
	{
		$opt_href = $option_fields_href->{$option_name} ;
	}
	return $opt_href ;
}



#----------------------------------------------------------------------------

=item B<modify_default($option_name, $default)>

Changes the default setting of the named option. Returns the option value if sucessful; undef otherwise

=cut

sub modify_default
{
	my $this = shift ;
	my ($option_name, $default) = @_ ;

	$default = '' unless defined $default ;
$this->_dbg_prt( ["Options: modify_default($option_name, $default)\n"] ) ;

	my $opt_href = $this->option_entry($option_name);

lib/App/Framework/Feature/Options.pm  view on Meta::CPAN

		# put field name first
		$spec = "$field" ;
		foreach my $fld (@fields)
		{
			next if $fld eq $field ;
			
	$this->_dbg_prt( [" + $fld\n"], 2 ) ;
			$spec .= '|' if $spec;
			$spec .= $fld ;
		}	
	}
	
	my $dest_type = "" ;
	if ($arg =~ /([\@\%])/i)
	{
		$dest_type = $1 ;
	}			

	my $arg_type = "" ;
	if ($arg =~ /([siof])/i)
	{
		$arg_type = $1 ;
		if ($arg_type eq 's')
		{
			if ($dest_type eq '%')
			{
				$spec .= " <key=value>" ;
			}
			else
			{
				$spec .= " <string>" ;
			}
		}
		elsif ($arg_type eq 'i')
		{
			$spec .= " <integer>" ;
		}
		elsif ($arg_type eq 'f')
		{
			$spec .= " <float>" ;
		}
		elsif ($arg_type eq 'o')
		{
			$spec .= " <extended int>" ;
		}
		else
		{
			$spec .= " <arg>"
		}
	}

$this->_dbg_prt( ["_process_option_spec() set: final pod spec=$spec arg=$arg\n"], 2 ) ;
				
	return ($field, $option_spec, $spec, $dest_type, $developer_only, \@fields, $arg_type) ;
			
}


#----------------------------------------------------------------------------
#
#=item B<_expand_options()>
#
#Expand any variables in the options
#
#=cut
#
sub _expand_options 
{
	my $this = shift ;

$this->_dbg_prt(["_expand_options()\n"]) ;

	my $options_href = $this->_options() ;
	my $options_fields_href = $this->_option_fields_hash() ;

	# get defaults & options
	my (%defaults, %values) ;
	foreach my $opt (keys %$options_fields_href)
	{
		$defaults{$opt} = $options_fields_href->{$opt}{'default'} ;
		$values{$opt} = $options_href->{$opt} if defined($options_href->{$opt}) ;
	}
$this->_dbg_prt(["_expand_options: defaults=",\%defaults," values=",\%values,"\n"]) ;

	# get replacement vars
	my @vars ;
	my $app = $this->app ;
	if ($app)
	{
		my %app_vars = $app->vars ;
		push @vars, \%app_vars ;
	}
	push @vars, \%ENV ;
	
#	## expand
#	$this->expand_keys(\%values, \@vars) ;
#	push @vars, \%values ;	# allow defaults to use user-specified values
#	$this->expand_keys(\%defaults, \@vars) ;

$this->_dbg_prt(["_expand_options - end: defaults=",\%defaults," values=",\%values,"\n"]) ;
	
	## Update
	foreach my $opt (keys %$options_fields_href)
	{
		# update defaults to reflect any user specified options
		$defaults{$opt} = $values{$opt} ;
		$options_fields_href->{$opt}{'default'} = $defaults{$opt} ;
		
		# update values
		$options_href->{$opt} = $values{$opt} if defined($options_href->{$opt}) ;
	}
}


# ============================================================================================
# END OF PACKAGE

=back

=head1 DIAGNOSTICS

Setting the debug flag to level 1 prints out (to STDOUT) some debug messages, setting it to level 2 prints out more verbose messages.

=head1 AUTHOR

Steve Price C<< <sdprice at cpan.org> >>

=head1 BUGS

None that I know of!

=cut


1;

__END__




( run in 0.574 second using v1.01-cache-2.11-cpan-5623c5533a1 )