NAME
Params::Callbacks - Make your subroutines accept blocking callbacks
SYNOPSIS
use Params::Callbacks 'callbacks', 'callback'; # Or use ':all' tag
use Data::Dumper;
$Data::Dumper::Indent = 0;
$Data::Dumper::Terse = 1;
sub foo
{
my ( $callbacks, @params ) = &callbacks; # If &callbacks makes the hairs
# on your neck standp, then use
# a cleaner alternative:
#
# - callbacks(@_), or ...
# - Params::Callbacks->new(@_)
return $callbacks->transform(@params);
}
# No callbacks; no change to result!
my @result_1 = foo( 0, 1, 2, 3 );
print Dumper( [@result_1] ), "\n"; # [0,1,2,3]
# With callback, result is transformed before being returned!
my @result_2 = foo( 0, 1, 2, 3, callback { 0 + 2 ** $_ } );
print Dumper( [@result_2] ), "\n"; # [1,2,4,8]
# With multiple callbacks, result is transformed in multiple stages
my @result_3 = foo( 0, 1, 2, 3, callback { 0 + 2 ** $_ } callback { 0 + 10 * $_ });
print Dumper( [@result_3] ), "\n"; # [10,20,40,80];
DESCRIPTION
Use this module to enable a function or method to accept optional blocking callbacks. Perhaps you would like to allow the caller to accept your function's return value as is, or to intercept, change, eliminate or otherwise process that reesult before it is finally returned.
Callbacks are passed to your function at the end of its parameter list. This module provides you with a means to identify and separate any callbacks from your function's arguments. It also provides dispatchers that will pass the return value into the callback chain and capture the result, ready to pass it back up to the caller.
Callbacks work simply enough. Like any function, they accept input in @_ and their output is returned explicitly or as the result of their terminal expression. When chaining together multiple callbacks, the dispatcher takes the function's return value and passes it to the first callback; the output from that callback is then passed to the following callback, and so on until their are no more callbacks to process the value. The result of the final callback is returned to the program ready to be returned to the caller.
As a convenience, callbacks also receive a copy of the value in $_.
If an empty list is returned then the value is discarded and the callback chain is terminated for that value.
Creating and passing callbacks into a function
##################################
# We define our MyModule.pm file #
##################################
package MyModule;
use Exporter;
use Params::Callbacks 'callbacks';
use namespace::clean; # Because you might do this ...
use Params::Callbacks 'callback'; # We do this to make "callback" available
our @EXPORT = 'callback'; # Maybe, maybe not. Up to you.
our @EXPORT_OK = 'awesome';
our @ISA = 'Exporter';
sub awesome {
my ( $callbacks, @names ) = &callbacks;
return $callbacks->transform(@names);
}
1;
#############################
# Meanwhile, back in main:: #
#############################
# No callbacks ...
#
use MyModule 'awesome';
my @team = awesome('Imran', 'Merlyn', 'Iain');
print "$_\n" for @team;
#
# Imran
# Merlyn
# Iain
#
# (Not so awesome.)
# With a callback ...
#
use MyModule 'awesome';
my @team = awesome('Imran', 'Merlyn', 'Iain', callback {
"$_, you're awesome!"
});
print "$_\n" for @team;
#
# Imran, you're awesome!
# Merlyn, you're awesome!
# Iain, you're awesome!
#
# (This time with added awesome!)
# With two callbacks ...
#
use MyModule 'awesome';
my @team = awesome('Imran', 'Merlyn', 'Iain', callback {
"$_, you're awesome!"
} # Comma is optional here.
callback {
my ($name) = @_;
print "$name\n";
return $name;
});
#
# Imran, you're awesome!
# Merlyn, you're awesome!
# Iain, you're awesome!
#
# (Moar awesome!)
METHODS
- new
-
Takes a list of scalar values, strips away any trailing callbacks and returns a new list containing a blessed array reference (the callback chain) followed by any values from the original list that weren't callbacks. The typical imagined use case is in processing a function's argument list
@_:sub my_function { ( $callbacks, @params ) = Params::Callbacks->new(@_); ... }The output list is packaged in such a way as to make parsing the argument list as easy as possible.
- transform
-
Transform a result set by passing it through all the stages of the callbacks pipeline. The transformation terminates if the result set is reduced to nothing, and an empty result set is returned.
Empty or not, this method always returns a list.
- smart_transform
-
Transform a result set by passing it through all the stages of the callbacks pipeline. The transformation terminates if the result set is reduced to nothing, and an empty result set is returned.
Empty or not, this method always returns a list if a list was wanted.
If a scalar is required, a scalar is returned. If the result set contains a single element then the value of that element will be returned, otherwise a count of the number of elements is returned.
EXPORTED FUNCTIONS
- callbacks
-
Takes a list of scalar values, strips away any trailing callbacks and returns a new list containing a blessed array reference (the callback chain) followed by any values from the original list that weren't callbacks. The typical imagined use case is in processing a function's argument list
@_:sub my_function { ( $callbacks, @params ) = callbacks(@_); ... } sub my_function { ( $callbacks, @params ) = &callbacks; ... }The output list is packaged in such a way as to make parsing the argument list as easy as possible.
- callback
-
A simple piece of syntactic sugar that announces a callback. The code reference it precedes is blessed as a
Params::Callbacks::Callbackobject, disambiguating it from unblessed subs that are being passed as standard arguments.Multiple callbacks may be chained together with or without comma separators:
callback { ... }, callback { ... }, callback { ... } # Valid callback { ... } callback { ... } callback { ... } # Valid, too!
REPOSITORY
BUG REPORTS
Please report any bugs to http://rt.cpan.org/
AUTHOR
Iain Campbell <cpanic@cpan.org>
COPYRIGHT AND LICENCE
Copyright (C) 2012-2015 by Iain Campbell
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.