NAME
Function::Parameters - subroutine definitions with parameter lists
SYNOPSIS
use Function::Parameters;
fun foo($bar, $baz) {
return $bar + $baz;
}
fun mymap($fun, @args) :(&@) {
my @res;
for (@args) {
push @res, $fun->($_);
}
@res
}
print "$_\n" for mymap { $_ * 2 } 1 .. 4;
use Function::Parameters 'proc';
my $f = proc ($x) { $x * 2 };
DESCRIPTION
This module lets you use parameter lists in your subroutines. Thanks to Devel::Declare it works without source filters.
WARNING: This is my first attempt at using Devel::Declare and I have almost no experience with perl's internals. So while this module might appear to work, it could also conceivably make your programs segfault. Consider this module alpha quality.
Basic stuff
To use this new functionality, you have to use fun
instead of sub
- sub
continues to work as before. The syntax is almost the same as for sub
, but after the subroutine name (or directly after fun
if you're writing an anonymous sub) you can write a parameter list in parens. This list consists of comma-separated variables.
The effect of fun foo($bar, $baz) {
is as if you'd written sub foo { my ($bar, $baz) = @_;
, i.e. the parameter list is simply copied into my
and initialized from @_.
Advanced stuff
You can change the name of the new keyword from fun
to anything you want by specifying it in the import list, i.e. use Function::Parameters 'spork'
lets you write spork
instead of fun
.
If you need subroutine attributes, you can put them after the parameter list with their usual syntax. There's one exception, though: you can only use one colon (to start the attribute list); multiple attributes have to be separated by spaces.
Syntactically, these new parameter lists live in the spot normally occupied by prototypes. However, you can include a prototype by specifying it as the first attribute (this is syntactically unambiguous because normal attributes have to start with a letter).
Normally, Perl subroutines are not in scope in their own body, meaning the parser doesn't know the name foo
or its prototype when processing sub foo ($) { foo $bar[1], $bar[0]; }
, parsing it as $bar->foo([1], $bar[0])
. Yes. You can add parens to change the interpretation of this code, but foo($bar[1], $bar[0])
will only trigger a foo() called too early to check prototype warning. This module attempts to fix all of this by adding a subroutine declaration before the definition, so the parser knows the name (and possibly prototype) while it processes the body. Thus fun foo($x) :($) { $x }
really turns into sub foo ($); sub foo ($) { my ($x) = @_; $x }
.
If you want to wrap Function::Parameters
, you may find import_into
helpful. It lets you specify a target package for the syntax magic, as in:
package Some::Wrapper;
use Function::Parameters ();
sub import {
my $caller = caller;
Function::Parameters::import_into $caller;
# or Function::Parameters::import_into $caller, 'other_keyword';
}
import_into
is not exported by this module, so you have to use a fully qualified name to call it.
AUTHOR
Lukas Mai, <l.mai at web.de>
COPYRIGHT & LICENSE
Copyright 2010 Lukas Mai.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.