NAME
Perinci::Access::InProcess - Use Rinci access protocol (Riap) to access Perl code
VERSION
version 0.01
SYNOPSIS
# in Your/Module.pm
package My::Module;
our %SPEC;
$SPEC{mult2} = {
v => 1.1,
summary => 'Multiple two numbers',
args => {
a => { schema=>'float*', req=>1, pos=>0 },
b => { schema=>'float*', req=>1, pos=>1 },
},
examples => [
{args=>{a=>2, b=>3}, result=>6},
],
};
sub mult {
my %args = @_;
[200, "OK", $args{a} * $args{b}];
}
$SPEC{multn} = {
v => 1.1,
summary => 'Multiple many numbers',
args => {
n => { schema=>[array=>{of=>'float*'}], req=>1, pos=>0, greedy=>1 },
},
};
sub multn {
my %args = @_;
my @n = @{$args{n}};
my $res = 0;
if (@n) {
$res = shift(@n);
$res *= $_ while $_ = shift(@n);
}
return [200, "OK", $res];
}
1;
# in another file
use Perinci::Access::InProcess;
my $pa = Perinci::Access::Process->new();
# list all functions in package
my $res = $pa->request(list => '/My/Module/', {type=>'function'});
# -> [200, "OK", ['/My/Module/mult2', '/My/Module/mult2']]
# call function
my $res = $pa->request(call => '/My/Module/mult2', {args=>{a=>2, b=>3}});
# -> [200, "OK", 6]
# get function metadata
$res = $pa->request(meta => '/Foo/Bar/multn');
# -> [200, "OK", {v=>1.1, summary=>'Multiple many numbers', ...}]
DESCRIPTION
This class implements Rinci access protocol (Riap) to access local Perl code. This might seem like a long-winded and slow way to access things that are already accessible from Perl like functions and metadata (in %SPEC
). Indeed, if you do not need Riap, you can access your module just like any normal Perl module.
The abstraction provides some benefits, still. For example, you can actually place metadata not in %SPEC
but elsewhere, like in another file or even database, or even by merging from several sources. By using this module, you don't have to change client code. This class also does some function wrapping to convert argument passing style or produce result envelope, so you a consistent interface.
Functions not accepting hash arguments
As can be seen from the Synopsis, Perinci expects functions to accept arguments as hash. If your function accepts arguments from array, add args_as
=> array
to your metadata property. When wrapping, Perinci::Sub::Wrapper can add a conversion code so that the function wrapper accepts hash as normal, but your function still gets an array. Example:
$SPEC{is_palindrome} = {
v => 1.1,
summary => 'Multiple two numbers',
args => {
a => { schema=>'float*', req=>1, pos=>0 },
b => { schema=>'float*', req=>1, pos=>1 },
},
};
sub mult2 {
my ($a, $b) = @_;
[200, "OK", $a*$b];
}
# called without wrapping
mult2(2, 3); # -> [200,"OK",6]
# called after wrapping, by default wrapper will convert hash arguments to
# array for passing to the original function
mult2(a=>2, b=>3); # -> [200,"OK",6]
Functions not returning enveloped result
Likewise, by default Perinci assumes your function returns enveloped result. But if your function does not, you can set result_naked
=> 1 to declare that. The wrapper code can add code to create envelope for the function result.
$SPEC{is_palindrome} = {
v => 1.1,
summary => 'Check whether a string is a palindrome',
args => {str => {schema=>'str*'}},
result => {schema=>'bool*'},
result_naked => 1,
};
sub is_palindrome {
my %args = @_;
my $str = $args{str};
$str eq reverse($str);
}
# called without wrapping
is_palindrome(str=>"kodok"); # -> 1
# called after wrapping, by default wrapper adds envelope
is_palindrome(str=>"kodok"); # -> [200,"OK",1]
Location of metadata
By default, the metadata should be put in %SPEC
package variable, in a key with the same name as the URI path leaf (use :package
) for the package itself). For example, metadata for /Foo/Bar/$var
should be put in $Foo::Bar::SPEC{'$var'}
, /Foo/Bar/
in $Foo::Bar::SPEC{':package'}. The metadata for the top-level namespace (
/
) should be put in $main::SPEC{':package'}
.
If you want to put metadata elsewhere, you can pass meta_accessor
=> 'Custom_Class'
to constructor argument, or set this in your module:
our $PERINCI_META_ACCESSOR = 'Custom::Class';
The default accessor class is Perinci::Access::InProcess::MetaAccessor. Alternatively, you can simply devise your own system to retrieve metadata which you can put in %SPEC
at the end.
METHODS
PKG->new(%opts) => OBJ
Instantiate object. Known options:
meta_accessor => STR
$pa->request($action => $uri, \%extra) => $res
Process Riap request and return enveloped result. This method will in turn parse URI and other Riap request keys into $req
hash, and then call action_ACTION
methods.
FAQ
Why %SPEC?
The name was first chosen when during Sub::Spec era, so it stuck. You can change it though.
SEE ALSO
AUTHOR
Steven Haryanto <stevenharyanto@gmail.com>
COPYRIGHT AND LICENSE
This software is copyright (c) 2012 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.
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 261:
Unterminated C<...> sequence