NAME
Sub::Spec - Subroutine metadata & wrapping framework
VERSION
version 0.08
SYNOPSIS
In your module:
package MyModule;
use 5.010;
use strict;
use warnings;
our %SPEC;
$SPEC{pow} = {
summary => 'Exponent a number',
description => <<'_',
...
_
args => {
base => [float => {summary=>"Base number", required=>1, arg_pos=>0}],
exp => [float => {summary=>"Exponent" , required=>1, arg_pos=>1}],
},
};
sub pow {
my (%args) = @_;
return [200, "OK", $arg{base} ** $arg{exp}];
}
Use your subs in Perl scripts/modules:
package MyApp;
use 5.010;
use Sub::Spec;
use MyModule qw(pow);
my $res;
# schema checking (NOT WORKING YET)
#$res = pow(base => 1); # [400, "Missing argument: exp"]
#$res = pow(base => "a"); # [400, "Invalid argument: base must be a float"]
$res = pow(base => 2, exp=>10); # [200, "OK", 1024]
say $res->[2];
Use positional arguments (NOT WORKING YET):
use MyModule pow => {args_positional=>1};
$res = pow(2, 10); # [200, "OK", 1024]
Return data only instead of with status code + message (NOT WORKING
YET):
use MyModule pow => {result_naked=>1};
say pow(base=>2, exp=>10); # 1024
say pow(base=>2); # now throws exception due to missing required arg 'exp'
Use your subs from the command line (see Sub::Spec::CmdLine for more
details):
% cat script.pl
#!/usr/bin/perl
use Sub::Spec::CmdLine qw(run);
run(module=>"MyModule", sub=>"pow");
% script.pl --help
(Usage message ...)
% script.pl --base 2 --exp 10
1024
% script.pl 2 10
1024
% script.pl 2
Error: Missing required argument exp
Create HTTP REST API from your subs (NOT WORKING YET, see
Sub::Spec::HTTP for more details):
% cat apid.pl
#!/usr/bin/perl
use Sub::Spec::HTTP qw(run);
run(port=>8000, module=>"MyModule", sub=>"pow");
1024
DESCRIPTION
NOTE: This module is still very early in development. Most of the
features are not even implemented yet.
Subroutines are an excellent unit of reuse, in some ways they are even
superior to objects (simpler, map better to HTTP/network programming due
to being stateless, etc). Sub::Spec aims to make your subs much more
useful, reusable, powerful. All you have to do is provide some metadata
(a spec) for your sub. See Sub::Spec::Manual::Spec for more details
about sub spec.
Below are the features provided by Sub::Spec:
* fast and flexible parameter checking
See Sub::Spec::Clause::args and Sub::Spec::Clause::result for more
details.
* positional as well as named arguments calling style
See the export clause -args_positional in Sub::Spec::Exporter.
* flexible exporting
See Sub::Spec::Exporter.
* easy switching between exception-based and return-code error
handling
See the export clause -exception in Sub::Spec::Exporter.
* command-line access
You can basically turn your subs into a command-line program with a
single line of code, complete with argument processing, --help,
pretty-printing of output, and bash tab-completion. See
Sub::Spec::CmdLine for more information.
* HTTP REST access
Creating an API from your subs is dead easy. See Sub::Spec::HTTP.
* generation of API documentation (POD, etc)
See Sub::Spec::Pod on how to generate POD and
Pod::Weaver::Plugin::SubSpec on how to do this when building dist
with Dist::Zilla.
See gen_usage() in Sub::Spec::CmdLine to generate text help message.
* execution time limits
See Sub::Spec::Clause::timeout.
* automatic retries
See Sub::Spec::Clause::retry.
* logging
* and more ...
CLAUSES
Here are the general clauses. For the rest of the clauses see respective
Sub::Spec::Clause::<CLAUSE_NAME>, e.g. Sub::Spec::Clause::args, etc.
* name
The name of the subroutine. Useful for generating help/usage
information, or when aliasing subroutines (and reusing the spec) and
finding out the canonical/original name of the subroutine.
* summary
A one-line summary. It should be plain text without any markup.
* description
A longer description. Currently the format of the text inside is not
yet specified. It is probably going to be Markdown, not POD/HTML.
Sub::Spec is extensible, you can add your own clauses (see
Sub::Spec::Manual::Spec for more information).
FAQ
See Sub::Spec::Manual::FAQ
SEE ALSO
Modules used
Data::Sah for schema checking.
Log::Any for logging.
Alternative modules
If you just want to give named arguments, you might want to consider
Sub::NamedParams.
You can check out Sub::Attempts for retries.
There are a gazillion modules for parameter checking. Data::Sah lists a
few of them.
AUTHOR
Steven Haryanto <stevenharyanto@gmail.com>
COPYRIGHT AND LICENSE
This software is copyright (c) 2011 by Steven Haryanto.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.