如果没有指定参数,则修改$ _

Joe*_*Fan 8 perl

我有这个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)

就个人而言,我只是避免$_像这样的词汇和丑陋的问题消失了.但如果你需要支持它,这是一种方式.