“Passing arguments to subroutine”-question?
-
28-09-2019 - |
Question
Is routine2 ok too or shouldn't I do this? (I don't need a copy of @list in the subroutine)
#!/usr/bin/perl
use 5.012;
use warnings;
my @list = 0 .. 9;
sub routine1 {
my $list = shift;
for (@$list) { $_++ };
return $list
}
my $l = routine1( \@list );
say "@$l";
sub routine2 {
for (@list) { $_++ };
}
routine2();
say "@list";
Solution
If it works for you, then it's ok too. But the first sub can do the job for any array you pass to it which makes it more general.
P.S. Remember that @_
contains aliases for the parameters passed to the function. So you could also use this:
sub increment { $_++ for @_ }
increment(@list);
OTHER TIPS
If you're worried about making the syntax look nice, try this:
sub routine3 (\@) {
for (@{$_[0]}) { $_++ }
}
my @list = (0 .. 9);
routine3(@list);
say "@list"; # prints 1 .. 10
This declares routine3
with a prototype - it takes an array argument by reference. So $_[0]
is a reference to @list
, no rather unsightly \
needed by the caller. (Some people discourage prototypes, so take this as you will. I like them.)
But unless this is a simplification for what your actual routine does, what I'd do is this:
my @list = 0 .. 9;
my @new_list = map { $_ + 1 } @list;
say "@new_list";
Unless routine
is actually really complicated, and it's vital somehow that you modify the original array, I'd just use map
. Especially with map
, you can plug in a subroutine:
sub complex_operation { ... }
my @new_list = map { complex_operation($_) } @list;
Of course, you could prototype complex_operation
with (_)
and then just write map(complex_operation, @list);
but I like the bracket-syntax personally.