Sub::Chain - Chain subs together and call in succession
version 0.012
my $chain = Sub::Chain->new(); $chain->append(\&wash, ['cold']); $chain->append(\&dry, [{tumble => 'low'}]); $chain->append(\&fold); my @clean_laundry = $chain->call(@clothes); # if only it were that easy
This module aims to provide a simple interface for chaining multiple subs (coderefs) together and executing them one after the other in a single call.
It was specifically designed to be built dynamically from a list of specifications provided at runtime to filter data through the specified list of functions.
Also see Sub::Chain::Named which appends subs to the chain by name rather than coderef.
my $chain = Sub::Chain->new(); my $chain = Sub::Chain->new( option => $value ); my $chain = Sub::Chain->new({option => $value});
Constructor. Takes a hash or hashref of arguments.
Accepts values as described in OPTIONS that will be used as defaults for any sub that doesn't override them.
$chain->append(\&sub, \@args, \%opts);
Append a sub to the chain. The \@args arrayref will be flattened and passed to the \&sub after any arguments to "call".
\@args
\&sub
sub sum { my $s = 0; $s += $_ for @_; $s; } $chain->append(\&sum, [3, 4]); $chain->call(1, 2); # returns 10 # equivalent to: sum(1, 2, 3, 4)
If you don't want to send any additional arguments to the sub an empty arrayref ([]) can be used.
[]
This method returns the object so that it can be chained for simplicity:
$chain->append(\&sub, \@args)->append(\&sub2)->append(\&sub3, [], \%opts);
The \%opts hashref can be any of the options described in "OPTIONS" to override the defaults on the object for this particular sub.
\%opts
$chain->call(@args);
Calls each method in the chain with the supplied (and any predetermined) arguments according to any predefined options.
my $sub = $chain->coderef; $sub->(@args);
Wrap $self->call in a closure. This is used to overload the function dereference operator so you can pretend the instance is a coderef: $chain->(@args)
$self->call
$chain->(@args)
These options can define how a sub should be handled. Specified in the options hashref for "append" they apply to that particular sub. Specified in the constructor they can set the default for how to handle any sub that doesn't override the option.
result
What to do with the result; Valid values are:
replace - replace the argument list with the return value of each sub
replace
discard - discard the return value of each sub
discard
The arguments to "call" are passed to each sub in the chain. When replace is specified the return value of one sub is the argument list to the next. This is useful, for instance, when chaining a number of data cleaning or transformation functions together:
sub add_uc { $_[0] . ' ' . uc $_[0] } sub repeat { $_[0] x $_[1] } $chain->append(\&add_uc)->append(\&repeat, [2]); $chain->call('hi'); # returns 'hi Hihi HI', similar to: my $s = 'hi'; $s = add_uc($s); $s = repeat($s, 2);
When discard is specified, the same arguments are sent to each sub. This is useful when chaining subs that are called for their side effects and you aren't interested in the return values.
# assume database handle has RaiseError set $chain ->append(\&log) ->append(\&save_to_database) ->append(\&email_to_user); # call in void context because we don't care about the return value $chain->call($object);
The default is replace since that (arguably) makes this module more useful.
on_undef
What to do when a value is undefined; Valid values are:
proceed - proceed as normal (as if it was defined)
proceed
skip - skip (don't call) the sub
skip
blank - initialize the value to a blank string
blank
The default is proceed.
This module started out as Data::Transform::Named, a named wrapper (like Sub::Chain::Named) around Data::Transform (and specifically Data::Transform::Map).
Data::Transform::Named
Sub::Chain::Named
As the module was nearly finished I realized I was using very little of Data::Transform (and its documentation suggested that I probably wouldn't want to use the only part that I was using). I also found that the output was not always what I expected. I decided that it seemed reasonable according to the likely purpose of Data::Transform, and this module simply needed to be different.
So I attempted to think more abstractly and realized that the essence of the module was not tied to data transformation, but merely the succession of simple subroutine calls.
I then found and considered Sub::Pipeline but needed to be able to use the same named subroutine with different arguments in a single chain, so it seemed easier to me to stick with the code I had written and just rename it and abstract it a bit further.
I also looked into Rule::Engine which was beginning development at the time I was searching. However, like Data::Transform, it seemed more complex than what I needed. When I saw that Rule::Engine was using [the very excellent] Moose I decided to pass since I was doing work on a number of very old machines with old distros and old perls and constrained resources. Again, it just seemed to be much more than what I was looking for.
Write a lot more tests
Improve documentation
Sub::Pipeline
Data::Transform
Rule::Engine
You can find documentation for this module with the perldoc command.
perldoc Sub::Chain
The following websites have more information about this module, and may be of help to you. As always, in addition to those websites please use your favorite search engine to discover more resources.
Search CPAN
The default CPAN search engine, useful to view POD in HTML format.
http://search.cpan.org/dist/Sub-Chain
RT: CPAN's Bug Tracker
The RT ( Request Tracker ) website is the default bug/issue tracking system for CPAN.
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Sub-Chain
CPAN Ratings
The CPAN Ratings is a website that allows community ratings and reviews of Perl modules.
http://cpanratings.perl.org/d/Sub-Chain
CPAN Testers
The CPAN Testers is a network of smokers who run automated tests on uploaded CPAN distributions.
http://www.cpantesters.org/distro/S/Sub-Chain
CPAN Testers Matrix
The CPAN Testers Matrix is a website that provides a visual overview of the test results for a distribution on various Perls/platforms.
http://matrix.cpantesters.org/?dist=Sub-Chain
CPAN Testers Dependencies
The CPAN Testers Dependencies is a website that shows a chart of the test results of all dependencies for a distribution.
http://deps.cpantesters.org/?module=Sub::Chain
Please report any bugs or feature requests by email to bug-sub-chain at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Sub-Chain. You will be automatically notified of any progress on the request by the system.
bug-sub-chain at rt.cpan.org
http://github.com/rwstauner/Sub-Chain
git clone http://github.com/rwstauner/Sub-Chain
Randy Stauner <rwstauner@cpan.org>
This software is copyright (c) 2010 by Randy Stauner.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install Sub::Chain, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Sub::Chain
CPAN shell
perl -MCPAN -e shell install Sub::Chain
For more information on module installation, please visit the detailed CPAN module installation guide.