我有这个trim
例程:
sub trim {
for (@_) {
s|^\s+||;
s|\s+$||;
}
}
Run Code Online (Sandbox Code Playgroud)
它"就地"修剪空白,即:
trim $x, $y;
Run Code Online (Sandbox Code Playgroud)
将修剪$ x和$ y的空白(修改它们).
我如何改进,trim
以便让我称之为:
trim;
Run Code Online (Sandbox Code Playgroud)
这将是:
trim $_;
Run Code Online (Sandbox Code Playgroud)
?
小智 11
只需检查是否没有提供参数:
use strict;
use warnings;
$_=" abc ";
sub trim
{
if(@_)
{
foreach my $i(@_)
{
$i=~s/^\s+//;
$i=~s/\s+$//;
}
}
else
{
s/^\s+//;
s/\s+$//;
}
}
trim;
print "!$_!\n"; #Throwing in exclamation points just to make sure white space is gone.
Run Code Online (Sandbox Code Playgroud)
这会产生输出
!abc!
Run Code Online (Sandbox Code Playgroud)
Eri*_*rom 11
所有你需要做的是替换@_
与@_ ? @_ : $_
在参数的for
循环.
sub trim {
for (@_ ? @_ : $_) {
s|^\s+||;
s|\s+$||;
}
}
Run Code Online (Sandbox Code Playgroud)
根据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]"
Run Code Online (Sandbox Code Playgroud)
就个人而言,我只是避免$_
像这样的词汇和丑陋的问题消失了.但如果你需要支持它,这是一种方式.