«Передача аргументов в подпрограмму» - вопрос? - PullRequest
1 голос
/ 25 ноября 2010

С рутиной2 тоже все в порядке или я не должен этого делать?(Мне не нужна копия @list в подпрограмме)

#!/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";

Ответы [ 2 ]

4 голосов
/ 25 ноября 2010

Если это работает для вас, то это тоже нормально. Но первый саб может выполнить работу для любого массива, который вы передаете ему, что делает его более общим.

P.S. Помните, что @_ содержит псевдонимы для параметров, передаваемых в функцию. Таким образом, вы также можете использовать это:

sub increment { $_++ for @_ }
increment(@list);
1 голос
/ 25 ноября 2010

Если вы беспокоитесь о том, чтобы синтаксис выглядел красиво, попробуйте следующее:

sub routine3 (\@) {
  for (@{$_[0]}) { $_++ }
}

my @list = (0 .. 9);
routine3(@list);
say "@list"; # prints 1 .. 10

Здесь объявляется routine3 с прототипом - он принимает аргумент массива по ссылке. Так что $_[0] - это ссылка на @list, а не довольно неприглядная \, необходимая вызывающей стороне. (Некоторые люди не одобряют прототипы, поэтому примите это как хотите. Они мне нравятся.)

Но если это не упрощение того, что делает ваша настоящая рутина, я бы сделал следующее:

my @list = 0 .. 9;
my @new_list = map { $_ + 1 } @list;
say "@new_list";

Если routine на самом деле действительно сложно, и как-то жизненно важно, чтобы вы изменили исходный массив, я бы просто использовал map. Особенно с map, вы можете подключить подпрограмму:

sub complex_operation { ... }

my @new_list = map { complex_operation($_) } @list;

Конечно, вы можете создать прототип complex_operation с (_), а затем просто написать map(complex_operation, @list);, но мне лично нравится синтаксис скобок.

...