Я изучаю Perl и понимаю, что распаковывать аргументы подпрограммы с помощью shift - обычная и общепринятая практика. Я также понимаю, что это обычная и приемлемая практика - опускать аргументы функции для использования массива @_
по умолчанию.
Принимая во внимание эти две вещи, если вы вызываете подпрограмму без аргументов, @_
может (и будет, если используется shift) быть изменен. Означает ли это, что вызов другой подпрограммы с аргументами по умолчанию или, фактически, использование массива @_
после этого, считается плохой практикой? Рассмотрим этот пример:
sub total { # calculate sum of all arguments
my $running_sum;
# take arguments one by one and sum them together
while (@_) {
$running_sum += shift;
}
$running_sum;
}
sub avg { calculate the mean of given arguments
if (@_ == 0) { return }
my $sum = &total; # gets the correct answer, but changes @_
$sum / @_ # causes division by zero, since @_ is now empty
}
Мое чутье подсказывает мне, что использование shift для распаковки аргументов на самом деле было бы плохой практикой, если только ваша подпрограмма не должна изменять переданные аргументы, но я читал в нескольких местах, включая переполнение стека, что это неплохая практика.
Таким образом, возникает вопрос: если использование сдвига является обычной практикой, всегда ли я должен предполагать, что переданный список аргументов может быть изменен в качестве побочного эффекта подпрограммы (например, подпрограммы &total
в приведенном примере)? Может быть, есть способ передать аргументы по значению, чтобы я мог быть уверен, что список аргументов не изменится, чтобы я мог использовать его снова (как в подпрограмме &avg
в цитируемом тексте)?
return undef;
вместоreturn;
дляavg
без аргументов (как и вы дляtotal
).avg
- функция, которая должна возвращать скаляр. Если он вернет меньше одного значения, это вызовет сюрпризы. например Следующее приведет к ошибке с пустым@data
:{ avg => avg(@data), ts => time() }
- person ikegami   schedule 31.12.2012