In a module (not written by me) I have a prototype sub that takes a code ref and returns result of eval:
sub proto (&) {
my $code = shift;
my $r = eval {&$code};
return $r;
}
sub foo {
my $x = 1;
my $y = proto { $x = $x 1; };
}
foo();
The prototype sub is called very often in many modules. Now I need to change it and want to add an optional parameter like:
sub proto (&) {
my $code = shift;
my $OptionalParameter = shift || 0;
...
}
sub foo {
my $x = 1;
my $OptionalParameter = 1;
my $y = proto { $x = $x 1; }, $OptionalParameter;
}
But that results in warning "Useless use of private variable in void context" for $OptionalParameter. I also changed prototype declaration to (&;$) which results in same warning.
If I remove the prototype declaration (&), I get syntax errors where proto is called: syntax error at Test.pl line 47, near "; }" Global symbol "$OptionalParameter" requires explicit package name (did you forget to declare "my $OptionalParameter"?) at TestQuery.pl line 47.
So, how can I declare a sub that takes a code ref and an optional parameter?
CodePudding user response:
use a ';' in the prototype declaration to separate mandatory and optional parameters. And don't include a comma after the code block:
sub foo(&;$) { my ($fn, $arg) = @_; ... }
foo { ... };
foo { ... } 1;
But in general it's best to avoid using prototypes unless you're trying to emulate the syntax of a built-in perl function:
sub foo { my ($fn, $arg) = @_; ... }
foo(sub { ... });
foo(sub { ... }, 1);