Acme-Sub-Parms
view release on metacpan or search on metacpan
lib/Acme/Sub/Parms.pod view on Meta::CPAN
=head1 NAME
Acme::Sub::Parms - Provides simple, fast parsing of named subroutine parameters
=head1 SYNOPSIS
use Acme::Sub::Parms;
################
# A simple function with two required parameters
sub simple_bind_parms_function {
BindParms : (
my $handle : handle;
my $thing : thing;
)
#...
}
################
# A complex method interface with multiple parameters
# and validation requirements
sub complex_bind_parms_function {
my $self = shift;
BindParms : (
my $handle : handle [required, is_defined, can=param];
my $thing : thing [optional, isa=CGI::Minimal];
my $another_thing : another [optional, type=SCALAR, callback=_legal_thing];
my $yathing : yathing [optional, is_defined];
my $defaulted : dthing [optional, default="help me"];
)
#...
}
=head1 DESCRIPTION
Acme::Sub::Parms uses a source filter to rewrite the code during the
module load with efficient inline parameter processing code that
handles some common cases for simple Perl style named parameter key/value
parameter lists. It can handle either case-sensitive or case-insensitive
parameters as desired.
In essence, it provides some syntactic sugar for parameter declaration
and validation.
Typical usage is follows:
sub a_function {
BindParms : (
my $somevariable : parameter_name [required];
my $anothervariable : another_parameter_name [optional];
)
#...
}
B<IMPORTANT:> The whitespace before and after the ':' in the
'BindParms : (' starting declaration B<IS NOT> optional.
Second, the entire declaration must be on one line: No line breaks in
the middle or other code on the line.
You can make the passed parameter names case insensitive by adding the
':normalize' option on the 'use' line.
Acme::Sub::Parms does not handle anonymous hashes for parameters. It
expects parameters lists to be passed as 'flat' lists. This is due to
performance issues. The additional code required to handle both 'flat'
and 'anon hash' parameters has a noticable performance hit for simple
cases. Since one of the goals of this module is to be B<fast> and a
survey of existing modules indicates most authors use 'flat' parameters
lists, that is what Acme::Sub::Parms does as well. If you prefer using
anon hashes. just dereference them before using them to call.
Good Example:
some_function('a_parm' => 'value);
sub some_function {
BindParms : (
my $variable : a_parm;
)
#.....
}
Example of dereferencing anon hash parms:
my $parms = { 'a_parm' => 'value' };
some_function(%$parms);
Broken Examples:
some_function({ 'a_parm' => 'value} }); # WILL NOT WORK
my $parms = { 'a_parm' => 'value' };
some_function($parms); # WILL NOT WORK
sub some_function {
BindParms : (
my $variable : a_parm;
)
#.....
}
=head1 'use' options
There are three compile-time 'use' options available.
use Acme::Sub::Parms qw(:no_validation :normalize :dump_to_stdout);
=over 4
=item :no_validation
This flags that bound parameters should B<NOT> be validated according
to any validation specifications.
If this flag is used, then parameters will be bound, callbacks and
defaults applied, but validation checking will be disabled. This
provides a significant performance boost to parameter processing
in mature code that doesn't need runtime parameter assertion checking.
=item :normalize
This flags that bound parameters should ignore the difference between
upper and lowercase names for parameters. This permits the caller to
use MixedCase, UPPERCASE, or lowercase parameters names interchangeably
(with a noticable performance penalty).
=item :dump_to_stdout
This signals that the code should be printed to STDOUT as the source
filter runs. This is useful primarily to see what the source filter
actually does, for debugging, or if you want to capture the transformed
code so it can be used B<without> needing Acme::Sub::Parms to be
installed at all.
This would typically be used by setting the flag on the
'use Acme::Sub::Parms', and then running
perl -c sourcefile > outputfile
(with 'sourcefile' and 'outputfile' replaced with the appropriate
filenames).
=back
=head1 Parameter Binding and Validation
A syntax is available to perform argument validation. This is both fast
and powerful, but has some caveats.
The basic format is as follows
BindParms : (
my $somevariable : parameter_name [required];
my $anothervariable : another_parameter_name [optional];
)
The format of each line of the binding declaration is formatted as:
<stuff being assigned to> : parameter_name [binding options];
The simplest possible binding is like the following:
BindParms : (
my $somevariable : parameter_name;
)
That declares that the required named parameter 'parameter_name' will
be bound to the lexical variable $somevariable.
parameter_name may B<NOT> contain whitespace, single or double quotes,
or a left bracket ('[') character. It must be a bare (unquoted) string.
Pretty much any expression that is legal to assign to may be used for
the left side. With the caveat that it B<CANNOT> contain the literal
string ' : ' (whitespace colon whitespace) as that will confuse the
line parser. This excludes the use of the trinary ( statement ? value : value)
conditional operator on the left side, but you shouldn't need it in this
context since there is sufficient power in the binding options to cover
the cases where you might want it.
lib/Acme/Sub/Parms.pod view on Meta::CPAN
requirement. It does not check for class inheritance or blessed objects.
If you specify a reference type or a class name it must match B<exactly>.
This can also be used for checking Perl's built-in reference types such
as 'HASH', 'ARRAY' or 'CODE'.
Note: This B<does not> verify that anything _was_ passed, only that
B<if> something was passed, it is of the specified type.
Examples:
# Optional 'HASH'
BindParms : (
my $data = thing [optional, type=HASH];
)
# Required 'Mammal' or 'Bacteria' or 'Virus' object
BindParms : (
my $lifeform = organism [type="Mammal Bacteria Virus"];
)
=back
=over 4
=item default=something | default="some thing with spaces"
The 'default' declaration allows the setting of default values for
optional parameters (it is implicit that if omitted the default value
is undef).
If the value contains whitespace (or if you want the empty string
value), you will need to use quotes around it.
'default' behaves differently for required and optional parameters:
For an optional parameter, it only activates if the parameter is
omitted completely. It will not kick in for a value that is passed
but has the undefined value.
For a required parameter, it only activates if the parameter is
undefined.
=back
=over 4
=item callback=function_name
The 'callback' declaration lets you specify a function name to be used
to perform validation on the parameter(s).
The syntax is simple: callback=validation_function_name
There is no support for method style calls, only ordinary function calls.
The callback function is called with three
parameters: ($field_name, $field_value, $arguments_anon_hash)
The $field_name and $field_value arguments are obvious,
the $arguments_anon_hash is a 'live' reference to a hash containing
all of the arguments being processed by BindParms block.
Because it is a 'live' hash reference, alterations to the hash will be
reflected in subsequent binding lines and in the final values bound.
This is a powerful, but simultaneously very dangerous feature. Use
this ability with caution.
The callback must return either a true or a false value (not the
literal words 'true' or 'false' but something that evaluates to
a true or false logical value) and a string with an error message
(if a false value was returned.)
Callback function example:
# Checking if the field value is an integer
sub _is_integer {
my ($field_name, $field_value, $args_hash) = @_;
unless (defined ($field_value)) { return (0, 'Not defined'); }
unless (int($field_value) eq $field_value) { return (0, 'Not an integer'); }
return 1;
}
Callbacks are a powerful feature that allow you to do complex
validation well beyond the capabilities of the simple BindParms
specifications. If you are finding yourself wishing that the syntax for
BindParms let you do more complicated things, then use a callback.
=back
=head1 CHANGES
1.03 2020.10.12 - Relicensed under MIT License. Maintainer updated. Build
configs updated. Set min version of Perl to 5.6. Added
'use warnings'. Misc file permissions updated. Added
GitHub repo to metadata.
1.02 2008.05.17 - Permissions fixes for build tools and added more examples
1.01 2008.05.16 - Fixed minor permissions problem
1.00 2008.05.13 - Initial public release.
=head1 ERRORS
Syntactic errors using Acme::Sub::Parms will generally cause
compilation errors near (but probably not exactly at) the line
containing the error. When you see that kind of error, look for a
syntax error in the declaration.
=head1 BUGS
You can't used parameters names containing single or double quotes,
whitespace or the '[' character. Line numbering can sometimes get
thrown off a little in error messages and I haven't been able to figure
a fix out yet.
=head1 TODO
Handle multiline argument declarations. Handle comments on BindParm
lines. Generate thread-safe parameter parsing code. Handle parameter
names containing single or double quotes, whitespace or the '[' character.
( run in 1.183 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )