package App::Framework::Feature ; =head1 NAME App::Framework::Feature - Application feature =head1 SYNOPSIS Features are accessed via the App::Framework object, for example: use App::Framework '+Config' ; App::Framework::Feature is to be derived from and cannot be accessed directly. =head1 DESCRIPTION Provides the base object from which all features must be derived. B<DOCUMENTATION TO BE COMPLETED> =cut use strict ; use Carp ; our $VERSION = "1.001" ; #============================================================================================ # USES #============================================================================================ use App::Framework::Base ; #============================================================================================ # OBJECT HIERARCHY #============================================================================================ our @ISA = qw(App::Framework::Base) ; #============================================================================================ # GLOBALS #============================================================================================ =head2 FIELDS The following fields should be defined either in the call to 'new()', as part of a 'set()' call, or called by their accessor method (which is the same name as the field): =over 4 =item B<app> - Parent application Set by App::Framework as a reference to the application object. If this is not set, then the feature will skip any application-specific logic (allowing a feature to be used in the user part of an application as a stand alone object). =item B<registered> - list of registered application functions ARRAY ref to list of functions that this feature wants to register in the application. When a registered function is called by the framework, then the feature's method (of the same name) is also called. Function name is of the form <name>_entry (called at the start of <name>) or <name>_exit (called at the end of <name>) =item B<name> - feature name Set to the feature name (by the App::Framework). This is the name used by the application to access the feature =back =cut my %FIELDS = ( 'app' => undef, 'registered' => [], 'name' => 'feature', 'feature_args' => "", # Feature-specific arguments string 'feature_options' => [], ); #============================================================================================ =head2 CONSTRUCTOR =over 4 =cut #============================================================================================ =item B< new([%args]) > Create a new feature. The %args are specified as they would be in the B<set> method. =cut sub new { my ($obj, %args) = @_ ; my $class = ref($obj) || $obj ; # Create object my $this = $class->SUPER::new( 'priority' => $App::Framework::Base::PRIORITY_DEFAULT, # will be overridden by derived object %args, ) ; ## do application-specific bits $this->register_app() ; return($this) ; } #============================================================================================ =back =head2 CLASS METHODS =over 4 =cut #============================================================================================ #----------------------------------------------------------------------------- =item B< init_class([%args]) > Initialises the object class variables. =cut sub init_class { my $class = shift ; my (%args) = @_ ; # Add extra fields $class->add_fields(\%FIELDS, \%args) ; # init class $class->SUPER::init_class(%args) ; } #---------------------------------------------------------------------------- =item B<allowed_class_instance()> Returns 0 since this class can not have a class instance object =cut sub allowed_class_instance { return 0 ; } #============================================================================================ =back =head2 OBJECT DATA METHODS =over 4 =cut #============================================================================================ ##----------------------------------------------------------------------------- # #=item B< feature_args([$args]) > # #Get/set the feature's arguments. If specified, I<$args> may be either an ARRAY ref (which is saved as-is), #or a SCALAR. In the case of the SCALAR, it is expected to be a space/comma separated list of argument #strings which are parsed and converted into an ARRAY ref # #=cut # #sub feature_args #{ # my $this = shift ; # my ($arg) = @_ ; # # if (defined($arg)) # { # if (ref($arg) eq 'ARRAY') # { # # use as-is # } # elsif (!ref($arg)) # { # # convert scalar # my @list ; # while ($arg =~ m/\s*([^\s,]+)[\s,]*/g) # { # push @list, $1 ; # } # # $arg = \@list ; # } # else # { # $arg = undef ; # } # } # # return $this->SUPER::feature_args($arg) ; #} ##----------------------------------------------------------------------------- # #=item B< feature_args([$args]) > # #Get/set the feature's arguments. If specified, I<$args> may be either an ARRAY ref (which is saved as-is), #or a SCALAR. In the case of the SCALAR, it is expected to be a space/comma separated list of argument #strings which are parsed and converted into an ARRAY ref # #=cut # #sub feature_args #{ # my $this = shift ; # my ($arg) = @_ ; # #print "feature_args($arg) [$this]\n" ; #$this->dump_callstack() ; # # return $this->SUPER::feature_args($arg) ; #} #============================================================================================ =back =head2 OBJECT METHODS =over 4 =cut #============================================================================================ #----------------------------------------------------------------------------- =item B< register_app() > Registers this feature with the parent application framework (if specified) =cut sub register_app { my $this = shift ; my $app = $this->app ; if ($app) { ## if we need to, register our methods with the application framework my $methods_aref = $this->registered ; if (@$methods_aref) { $app->feature_register($this->name, $this, @$methods_aref) ; } } } # ============================================================================================ # 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__