App-Framework
view release on metacpan or search on metacpan
lib/App/Framework/Core.pm view on Meta::CPAN
$this->_dispatch_exit_features() ;
$this->exit(0) ;
}
#----------------------------------------------------------------------------
=item B<getopts()>
Convert the (already processed) options list into settings.
Returns result of calling GetOptions
=cut
sub getopts
{
my $this = shift ;
$this->_dispatch_entry_features() ;
# Parse options using GetOpts
my $opt = $this->feature('Options') ;
my $args = $this->feature('Args') ;
my $ok = $opt->get_options() ;
# If ok, get any specified filenames
if ($ok)
{
# Get args
my $arglist = $args->get_args() ;
$this->_dbg_prt(["getopts() : arglist=", $arglist], 2) ;
}
## Expand vars
my %values ;
my ($opt_values_href, $opt_defaults_href) = $opt->option_values_hash() ;
my ($args_values_href) = $args->args_values_hash() ;
%values = (%$opt_values_href) ;
my %args_clash ;
foreach my $key (keys %$args_values_href)
{
if (exists($values{$key}))
{
$args_clash{$key} = $args_values_href->{$key} ;
}
else
{
$values{$key} = $args_values_href->{$key} ;
}
}
my @vars ;
my %app_vars = $this->vars ;
push @vars, \%app_vars ;
push @vars, \%ENV ;
## expand all vars
$this->expand_keys(\%values, \@vars) ;
# set new values
foreach my $key (keys %$opt_values_href)
{
$opt_values_href->{$key} = $values{$key} ;
}
foreach my $key (keys %$args_values_href)
{
$args_values_href->{$key} = $values{$key} ;
}
## handle any name clash
if (keys %args_clash)
{
unshift @vars, \%values ;
$this->expand_keys(\%args_clash, \@vars) ;
# set new values
foreach my $key (keys %args_clash)
{
$args_values_href->{$key} = $args_clash{$key} ;
}
}
## update settings
$opt->option_values_set($opt_values_href, $opt_defaults_href) ;
$args->args_values_set($args_values_href) ;
$this->_dispatch_exit_features() ;
return $ok ;
}
#----------------------------------------------------------------------------
=item B<app_start()>
Set up before running the application.
Calls the following methods in turn:
* getopts
* [internal _expand_vars method]
* options
* (Application registered 'app_start' function)
=cut
sub app_start
{
my $this = shift ;
$this->_dispatch_entry_features() ;
## process the data
$this->feature('data')->process() ;
## allow features to add their options
my $features_aref = $this->feature_list() ;
foreach my $feature (@$features_aref)
{
my $feature_obj = $this->feature($feature) ;
my $feature_options_aref = $feature_obj->feature_options() ;
if (@$feature_options_aref)
{
$this->feature('Options')->append_options($feature_options_aref, $feature_obj->class) ;
}
}
## Add user-defined options last
$this->feature('Data')->append_user_options() ;
## Get options
# NOTE: Need to do this here so that derived objects work properly
my $ret = $this->getopts() ;
## Expand any variables in the data
$this->_expand_vars() ;
# Handle options errors here after expanding variables
unless ($ret)
{
$this->usage('opt') ;
$this->exit(1) ;
}
# get options
my %options = $this->options() ;
## function
$this->_exec_fn('app_start', $this, \%options) ;
$this->_dispatch_exit_features() ;
}
#----------------------------------------------------------------------------
=item B<application()>
Execute the application.
Calls the following methods in turn:
* (Application registered 'app' function)
=cut
sub application
{
my $this = shift ;
$this->_dispatch_entry_features() ;
## Execute function
my %options = $this->options() ;
## Check args here (do this AFTER allowing derived objects/features a chance to check the options etc)
$this->feature("Args")->check_args() ;
# get args
my %args = $this->feature("Args")->arg_hash() ;
## Run application function
$this->_exec_fn('app', $this, \%options, \%args) ;
## Close any open arguments
$this->feature("Args")->close_args() ;
$this->_dispatch_exit_features() ;
}
#----------------------------------------------------------------------------
=item B<app_end()>
lib/App/Framework/Core.pm view on Meta::CPAN
sub _register_var
{
my $this = shift ;
my ($type, $external_name, $field_name) = @_ ;
my $package = $this->package() ;
local (*alias); # a local typeglob
$this->_dbg_prt(["_register_var($type, $external_name, $field_name)\n"], 2) ;
# We want to get access to the stash corresponding to the package
# name
no strict "vars" ;
no strict "refs" ;
*stash = *{"${package}::"}; # Now %stash is the symbol table
if (exists($stash{$external_name}))
{
*alias = $stash{$external_name} ;
$this->_dbg_prt([" + found $external_name in $package\n"], 2) ;
if ($type eq 'SCALAR')
{
if (defined($alias))
{
$this->set($field_name => $alias) ;
}
}
if ($type eq 'ARRAY')
{
# was - if (defined(@alias)) - removed due to "deprecated" warning
if (@alias)
{
$this->set($field_name => \@alias) ;
}
}
if ($type eq 'HASH')
{
if (%alias)
{
$this->set($field_name => \%alias) ;
}
}
elsif ($type eq 'CODE')
{
if (defined(&alias))
{
$this->_dbg_prt([" + + Set $type - $external_name as $field_name\n"], 2) ;
$this->set($field_name => \&alias) ;
}
}
}
}
#----------------------------------------------------------------------------
#
#=item B<_expand_vars()>
#
#Run through some of the application variables/fields and expand any instances of variables embedded
#within the values.
#
#Example:
#
# __DATA_
#
# [SYNOPSIS]
#
# $name [options] <rrd file(s)>
#
#Here the 'synopsis' field contains the $name field variable. This needs to be expanded to the value of $name.
#
#NOTE: Currently this will NOT cope with cross references (so, if in the above example $name also contains a variable
#then that variable may or may not be expanded before the synopsis field is processed)
#
#
#=cut
#
sub _expand_vars
{
my $this = shift ;
$this->_dbg_prt(["_expand_vars() - START\n"], 2) ;
# Get hash of fields
my %fields = $this->vars() ;
#$this->_dbg_prt([" + fields=", \%fields], 2) ;
# work through each field, create a list of those that have changed
my %changed ;
foreach my $field (sort keys %fields)
{
# Skip non-scalars
next if ref($fields{$field}) ;
# First see if this contains a '$'
$fields{$field} ||= "" ;
my $ix = index $fields{$field}, '$' ;
if ($ix >= 0)
{
$this->_dbg_prt([" + + $field = $fields{$field} : index=$ix\n"], 3) ;
# Do replacement
$fields{$field} =~ s{
\$ # find a literal dollar sign
\{{0,1} # optional brace
(\w+) # find a "word" and store it in $1
\}{0,1} # optional brace
}{
no strict 'refs'; # for $$1 below
if (defined $fields{$1}) {
$fields{$1}; # expand global variables only
} else {
"\${$1}"; # leave it
}
}egx;
$this->_dbg_prt([" + + + new = $fields{$field}\n"], 3) ;
# Add to list
$changed{$field} = $fields{$field} ;
}
}
$this->_dbg_prt([" + changed=", \%changed], 2) ;
# If some have changed then set them
if (keys %changed)
{
$this->_dbg_prt([" + + set changed\n"], 2) ;
$this->set(%changed) ;
}
$this->_dbg_prt(["_expand_vars() - END\n"], 2) ;
}
#----------------------------------------------------------------------------
=item B<debug_prt($items_aref [, $min_debug])>
Print out the items in the $items_aref ARRAY ref iff the application's debug level is >0.
If $min_debug is specified, will only print out items if the application's debug level is >= $min_debug.
=cut
sub debug_prt
{
my $this = shift ;
my ($items_aref, $min_debug) = @_ ;
$min_debug ||= 1 ;
## check debug level setting
if ($this->options->option('debug') >= $min_debug)
{
$this->prt_data(@$items_aref) ;
}
}
# ============================================================================================
# PRIVATE FUNCTIONS
# ============================================================================================
#----------------------------------------------------------------------------
#
#=item B<_dumpisa(package)>
#
#Starting at I<package>, show the parents
#
#=cut
#
sub _dumpisa
{
no strict "vars" ;
no strict "refs" ;
my ($packageName, $level) = @_;
if (!defined($level))
{
print "#### PACKAGE: $packageName ISA HIERARCHY ###########################\n" ;
}
else
{
print " "x$level ;
print "$packageName\n" ;
}
foreach my $isa (@{"${packageName}::ISA"})
( run in 1.029 second using v1.01-cache-2.11-cpan-5623c5533a1 )