Perl:还有比$ var = $ _更好的东西吗?

时间:2011-11-18 14:48:21

标签: perl variable-assignment

这不是一个重要的问题而且我知道,buuut $var = $_;看起来很蹩脚,是否有更好(更短)的方式进行分配?

澄清我的问题:我知道我可以轻松地在代码中使用$_(这就是我喜欢的原因),但有时我需要存储$_并在$_上执行某些操作然后返回$_的旧值(例如)。

9 个答案:

答案 0 :(得分:8)

在新的词法范围内,您可以本地化$ _,这将阻止该范围内的任何修改影响其在该范围之外的值。

澄清一个例子是必要的:

$_ = 1;
say;
{ # open a new scope
    local $_ = 3;
    $_++;
    say;
} # close the scope
say;

这应该打印

1
4
1

我觉得编写在内部广泛使用$ _的函数非常有价值,因为当他们在周围范围内破坏$ _时我不喜欢它。但是,您也可以使用它来“预留”变量并使用它的新版本。

答案 1 :(得分:6)

在许多情况下,这是不必要的。例如:

foreach my $var (@array) {
  dostuff($var);
}

my $var;
while ($var = <>) {
  chomp($var);
  dostuff($var);
}

while (<>) {
  chomp;
  dostuff($_);
}

答案 2 :(得分:4)

为什么要$var = $_?只需使用$_或将其作为参数传递给函数,在函数中调用它$var

答案 3 :(得分:4)

根据OP请求,我将发表评论作为答案。

看起来您在询问是否有更好或更短的方式来编写$var = $_(或获得该功能)。对我来说,这是一个相当奇怪的要求,因为:

  • $var = $_已经差不多了,
  • 没有比使用平等更好的方法来进行分配 符号

答案 4 :(得分:3)

所有好的答案。我想再提供一个与“只使用$_”相关的例子,如@awm所说。

10分钟前我刚刚写了这些文字:

sub composite
{
   foreach my $element (@_)
   {
     # do something ...
   }
}

sub simple
{
  &composite( $_[ int rand @_ ] );
}

这是 Perl Golf cit.),不推荐使用。

如果您需要在其他地方存储$_,并且在一段时间后使用它的原始值,您应该执行分配。

答案 5 :(得分:3)

使用local

$_ = 1;
{
    local $_ = 2;
    say;           # prints 2
}
say;               # prints 1

答案 6 :(得分:3)

也许通常名为apply的功能正是您所寻找的。 Apply就像map一样,除了它首先复制其参数:

<强> apply {CODE} LIST

apply a function that modifies $_ to a shallow copy of LIST and returns the copy

    print join ", " => apply {s/$/ one/} "this", "and that";
    > this one, and that one

这是我的一个模块的实现:

http://search.cpan.org/perldoc?List::Gen#apply

答案 7 :(得分:2)

您可以使用map通过转换现有数组来生成新数组:

my @squares = map { $_**2 } 1..10 ;         # 1,4,9,16,25,36,49,64,81,100

my @after   = map { process($_) } @before ; # @before unchanged, @after created

答案 8 :(得分:1)

您似乎想要访问$_本地值的下推堆栈。那可能很酷。但是,您可以自己执行某些这样的事情。我可以告诉你基础知识。

our @A;           # declare a stack
*::A = *A{ARRAY}; # "Globalize" it if necessary.

sub pd (&;@) # <- block operator prototype indicating language sugar
{ 
    # I would have really preferred to do a push here.
    local @A = ( @A, $_ ); 
    # pull the block argument
    my $block = shift;
    # Ensure at least one execution
    @_ = $_ unless @_;
    # + Scalar behavior option #1
    # return $block->( local $_ = shift ) if not wantarray // 1; 
    # + Scalar behavior option #2
    # unless ( wantarray // 1 ) {
    #     my $result;
    #     while ( @_ ) { 
    #         local $_ = shift;
    #         return $result if defined( $result = $block->( $_ ));
    #     }
    #     return;
    # }
    # Standard filter logic
    return map { $block->( $_ ) } @_;
}

这是基于此的简单列表理解:

my @comp 
    = map { pd { pd { join '', @A[-2,-1], $_ } qw<g h> } qw<d e f>; } qw<a b c>
    ;

这是@comp

@comp: [
         'adg',
         'adh',
         'aeg',
         'aeh',
         'afg',
         'afh',
         'bdg',
         'bdh',
         'beg',
         'beh',
         'bfg',
         'bfh',
         'cdg',
         'cdh',
         'ceg',
         'ceh',
         'cfg',
         'cfh'
       ]