I was hoping that with the signatures feature in Perl 5 (e.g. in version 5.34.0), something like this would be possible:
use feature qw{ say signatures };
&test(1, (2,3,4), 5, (6,7,8));
sub test :prototype($@$@) ($a, @b, $c, @d) {
say "c=$c";
};
Or perhaps this:
sub test :prototype($\@$@) ($a, \@b, $c, @d) {
}
(as suggested here: https://www.perlmonks.org/?node_id=11109414).
However, I have not been able to make that work. My question is: With the signatures feature, is it possible to pass more than one array to a subroutine?
Alternatively: Even with signatures, is the only way to pass arrays by reference? That is to say: Are there any alternatives to passing by reference, e.g.:
sub test($a, $b, $c, @d) {
my @b = @{$b};
}
Many thanks!
(P.S.: If there's a solution for arrays, then there'd be one for hashes as well, so I haven't spelled that out above.)
CodePudding user response:
With the signatures feature, is it possible to pass more than one array to a subroutine?
Yes you can do this:
use v5.22.0; # experimental signatures requires perl >= 5.22
use feature qw(say);
use strict;
use warnings;
use experimental qw(signatures);
sub test :prototype($\@$\@) ($a, $b, $c, $d) {
say "c=$c";
}
my @q = (2,3,4);
my @r = (6,7,8);
test(1, @q, 5, @r);
Output:
c=5
CodePudding user response:
As per suggestion in comment thread, summarising some of the ideas in a separate answer:
Proposed solution by Håkon Hægland
sub test :prototype($\@$\@) ($a, $b, $c, $d) {
say "c=$c";
say @$b;
}
my @q = (2,3,4);
my @r = (6,7,8);
test(1, @q, 5, @r);
The usual pass-by-reference
Note that this is different from traditional pass by reference:
my @q = (2,3,4);
my @r = (6,7,8);
sub test1 :prototype($$$$) ($a, $b, $c, $d) {
say "c=$c";
say @$b;
}
test1(1, \@q, 5, \@r);
Håkon's solution has the benefit of validation (and means that args are passed as @b
rather than \@b
).
Improvement with declared_refs
Diab Jerius suggested declared_refs, which is offers alternative syntax:
use v5.22.0;
use feature qw(say);
use strict;
use warnings;
use experimental qw(signatures declared_refs);
sub test :prototype($\@$\@) ($a, $b, $c, $d) {
say "c=$c";
say @$b;
my \@bb = $b;
say @bb;
}
What I (original poster) had hoped.
I was hoping that (mainly for optics) this would be possible
sub test :prototype($@$@) ($a, @b, $c, @d) {
say @b;
};