Все, что вам нужно сделать, это заменить @_
с @_ ? @_ : $_
в аргументе к петле for
,
sub trim {
for (@_ ? @_ : $_) {
s|^\s+||;
s|\s+$||;
}
}
За ответ Ikegami, есть нытье вопрос о том, что делать фитофтороз что лексическая $_
(объявленный с my $_;
), так что версия $_
не является глобальной, но привязан к лексической площадке ,
(_)
прототипа является одним из способов решить эту проблему, но это также означает, что подпрограмма принимает только один аргумент, и что аргумент имеет скалярный контекст, что делает его столь же плохо, как ($)
прототипа (в связи с непредвиденными последствиями скалярного контекста).
При попытке сделать магию на лексике, модуль PadWalker пригодится. Так вот версия, которая работает правильно в списках, работает как на лексическую и глобальную $_
, и не накладывает скалярный контекст на месте вызова:
use PadWalker 'peek_my';
sub trim {
my $it;
unless (@_) {
my $pad = peek_my 1;
$it = $$pad{'$_'} || \$::_
}
for (@_ ? @_ : $$it) {
s/^\s+//;
s/\s+$//;
}
}
{local $_ = " a "; trim; say "[$_]"} # prints "[a]"
{my $_ = " a "; trim; say "[$_]"} # prints "[a]"
{my $x = " a "; trim $x; say "[$x]"} # prints "[a]"
Лично я просто избежать лексических $_
и уродливые проблемы, как это просто исчезают. Но если вам нужно его поддержать, это путь.
В re lexical '$ _': не делайте этого. :) – tchrist
@tchrist, так что не используйте 'given', затем ...? – ikegami
'sub trim (_ @) {...}' –