NAME
Su - A simple application layer to divide and integrate data and processes in the Perl program.
SYNOPSIS
my $su = Su->new;
my $proc_result = $su->resolve('process_id');
print $proc_result;
DESCRIPTION
Su is a simple application framework that works as a thin layer to divide data and process in your Perl program. This framework aims an ease of maintenance and extension of your application.
Su is a thin application layer, so you can use Su with many other frameworks you prefer in many cases.
Note that Su framework has nothing to do with unix su
(switch user) command.
Divide data and process in your code
For divide data and process, Su framework provides Model and Process classes. Model and Process classes represent data and process of your application. You define the data used in the application to the Model, and describe own code to the Process. Models and Processes are just a simple Perl module and not required to implement any base class of Su framework.
Integrate model and process in your code
Su integrates Model and Process classes using the definition file. The definition file also a Perl module. Su read the definition file and inject the data defined in the Model to the corresponding Process, then execute that Process.
Other features Su provides
Su also provides some useful features.
For convinience, Su framework provides the methods to generate the template of the Model and Process classes.
Su also provides logging and string template. These features are frequently used in many kinds of applications and you can use these features without any other dependencies. Surely you can use other modules you prefer with Su framework.
Standard usage
Generate Su files
Described above, Su is composed of Model, Process and Definition module. The Definition module named Defs.pm
integrates Model and Processes. So, at first, we generate these files from the command line.
To generate the Model file, type the following command.
perl -MSu=base,./lib/ -e 'Su::gen_model("Pkg::SomeModel")'
To generate the Process file, type the following command.
perl -MSu=base,./lib/ -e 'Su::gen_proc("Pkg::SomeProc")'
To generate the definition file, type the following command.
perl -MSu=base,./lib/ -e 'Su::gen_defs()'
The 'base' parameter means the base directory of the modules to generate.
Instead of these three commands, you can use the simplified single command.
perl -MSu -e 'Su::init("MyPkg")'
This command generates these three files at once.
Describe Setting file
To call the generated process, you need to define the entry to the generated definition file Defs/Defs.pm.
The Definition file is a perl module, and define the entry at the $defs
field of it.
my $defs =
{
some_entry_id =>
{
proc=>'Pkg::SomeProc',
model=>'Pkg::SomeModel',
},
};
In this case, the entry id is specified as some_entry_id
. The Process and Model modules are specified at the field of proc
and model
, respectively.
Set data to the Model
You can define some data to the $model
field of the generated Model.
For example, edit Pkg::SomeModel
module like the following.
my $model=
{
field_a =>'value_a'
};
Describe the Process
You can describe own code to the process
method of the generated Process.
In this case you can edit Pkg::SomeProc
like the following.
sub process{
my $self = shift if ref $_[0] eq __PACKAGE__;
my $param = shift;
my $ret = "param:" . $param . " and model:" . $model->{field_a};
return $ret;
}
Note that you can refer to the model data previouslly defined at the $model
field of the Model class via the $model
field.
The Process and Model modules are tied as defined in Defs module by Su framework.
Call the Process via Su
You can call the process via Su by passing the entry id which defined in the definition file Defs.pm.
my $su = Su->new;
my $result = $su->resolve('some_entry_id');
Additional usage - Filters
The map, reduce and scalar filters can be defined in the definition file.
These filters are Perl module which has the method for filtering the result of the process. (In case of map
filter, method name is map_filter
.) You can chain filter modules. The following code is a sample definition which uses these filters.
my $defs =
{
some_proc_id =>
{
proc=>'MainProc',
model=>'Pkg::MainModel',
map_filter=>'Pkg::FilterProc', # or ['Filter01','Filter02']
reduce_filter=>'Pkg::ReduceProc', # reduce filter can only apply at once.
scalar_filter=>'Pkg::ScalarProc', # or ['Filter01','Filter02']
}
};
The filters Su recognizes are the followings.
- map_filter
-
The perl module which has
map_filter
method. The parameter of this method is an array which is a result of the 'process' method of the Process or the chained map filter. Themap_filter
method must return the array data type. - reduce_filter
-
The perl module which has
reduce_filter
method. The parameter of this method is an array which is a result of the 'process' method of the Process. If the map_filters are defined in theDefs.pm
, then the map_filters are applied to the result of the process before passed to the reduce filter. Thereduce_filter
method must return the scalar data type. Note that this method can't chain. - scalar_filter
-
The perl module which has
scalar_filter
method. The parameter of this method is a scalar which is a result of the 'process' method of the Process. If the map_filters and recude_filters are defined in theDefs.pm
, then these filters are applied to the result of the process before passed to the scalar filter.The
scalar_filter
method must return the scalar data type.
METHODS
- import()
-
use Su base=>'./base', proc=>'tmpls', model=>'models', defs=>'defs';
If you want to specify some parameters from the command line, then it becomes like the following.
perl -Ilib -MSu=base,./base,proc,tmpls,defs,models -e '{print "do some work";}'
- setup()
-
Instead of loading the definition form the Definition file, this method set the definition directly.
Su::setup( menu =>{proc=>'MenuTmpl', model=>qw(main sites about)}, book_comp =>{proc=>'BookTmpl', model=>'MenuModel'}, menuWithArg =>{proc=>'MenuTmplWithArg', model=>{field1=>{type=>'string'},field2=>{type=>'number'}}}, );
- new()
-
Instantiate the Su instance. To make Su instance recognize the custom definition module, you can pass the package name of the definition file as a parameter.
my $su = Su->new;
my $su = Su->new('Pkg::Defs');
my $su = Su->new(defs_module=>'Pkg::Defs');
- resolve()
-
Find the passed id from the definition file and execute the corresponding Process after the injection of the corresponding Model to the Process.
An example of the definition in Defs.pm is like the following.
my $defs = { entry_id => { proc=>'Pkg::SomeProc', model=>'Pkg::SomeModel', }, };
Note that
proc
field in the definition file is required, butmodel
field can omit. To execute the process descired in this example, your code will become like the following.my $ret = $su->resolve('entry_id');
If you pass the additional parameters to the resolve method, these parameters are passed to the
process
method of the Process.my $ret = $su->resolve('entry_id', 'param_A', 'param_B');
If the passed entry id is not defined in Defs file, then the error is thorwn.
Definition can be also specified as a parameter of the
resolve
method like the following.$su->resolve({ proc=>'MainProc', model=>['Model01','Model02','Model03'], }); $su->resolve( { proc => 'Sample::Procs::SomeModule', model => { key1 => { 'nestkey1' => ['value'] } }, }, 'arg1', 'arg2');
Optional Usage - Model Definition
This method works differently according to the style of the model definition.
If the
model
field is a string, then Su treat it as a name of the Model, load it's class and set it'smodel
field to the Process.some_entry_id =>{proc=>'ProcModule', model=>'ModelModule'},
If the
model
field is a hash, Su set it's hash to themodel
field of the Process directly.some_entry_id =>{proc=>'ProcModule', model=>{key1=>'value1',key2=>'value2'}},
If the
model
field is a reference of the string array, then Su load each element as Model module and execute Process with each model.some_entry_id =>{proc=>'TmplModule', model=>['ModelA', 'ModelB', 'ModelC']},
In this case, Process is executed with each Model, and the array of each result is returned.
Optional Usage - Filters
If a definition has any filter related fields, then these filter methods are applied before Su return the result of the process method. The module specified as a filter must has the method which corresponds to the filter type. About usable filter types, see the section of
map_filter
,reduce_filter
,scalar_filter
.These filter methods receive the result of the process or previous filter as a parameter, and return the filtered result to the caller or next filter.
Following is an example of the definition file to use post filter.
my $defs = { exec_post_filter => { proc=>'MainProc', model=>['Model01','Model02','Model03'], post_filter=>'FilterProc' },
Multiple filters can be set to the definition file.
exec_post_filter_chain => { proc=>'MainProc', model=>['Model01','Model02','Model03'], post_filter=>['FilterProc1', 'FilterProc1'] } };
An example of the
map_filter
method in the filter class is the following. Themap_filter
receives an array of previous result as a parameter and return the result as an array.sub map_filter { my $self = shift if ref $_[0] eq __PACKAGE__; my @results = @_; for (@results) { # Do some filter process. } return @results; }
An example of the
reduce_filter
method in the filter class is the following. Thereduce_filter
receives an array as a parameter and return the result as a scalar.sub reduce_filter { my $self = shift if ref $_[0] eq __PACKAGE__; my @results = @_; # For example, just join the result and return. return join( ',', @results ); }
An example of the
scalar_filter
method in the filter class is the following. Thescalar_filter
receives a scalar as a parameter and return the result as a scalar.sub scalar_filter { my $self = shift if ref $_[0] eq __PACKAGE__; my $result = shift; # Do some filter process to the $result. return $result; }
- init()
-
Generate the initial files at once. The initial files are composed of Defs, Model and Process module.
Su::init('PkgName');
- gen_model()
-
Generate a Model file.
Su::gen_model("SomePkg::SomeModelName") perl -MSu=base,./lib/ -e 'Su::gen_model("Pkg::ModelName")'
- gen_proc()
-
Generate a Process file.
perl -MSu=base,./lib/ -e 'Su::gen_proc("Pkg::TestProc")'
- gen_defs()
-
Generate a definition file.
perl -MSu=base,./lib/ -e 'Su::gen_defs()'
You can specify the package name of the definition file as a parameter.
gen_defs('Defs::Defs')
Also you can specify other parameters as hash.
gen_defs(name=>'Defs::Defs',package=>'pkg', proc=>'MyProc',model=>'MyModel')
SEE ALSO
Su::Process,Su::Model,Su::Template,Su::Log
AUTHOR
lottz <lottzaddr@gmail.com>
LICENSE
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.