Perl子例程中的本地$ _

时间:2014-11-03 09:46:42

标签: perl

写这个是正确的吗?

sub foobar {
   local $_ = $_[0] if @_;
   s/foo/bar/;
   $_;
}

如果没有$_给出的参数,那么我们的想法是chomp。然后我可以写

foobar($_);

&foobar;

4 个答案:

答案 0 :(得分:3)

这不正确,不。麻烦的是你不能有条件local某些东西 - 它本地化,或者不是。

而不是这样做,我建议您将其本地化,然后从@_

有条件地复制
local $_ = $_;
$_ = shift if @_;

这样,$_始终是本地化的,但只有在第一个位置参数存在的情况下才有条件地复制。

答案 1 :(得分:3)

如果你想在子程序中使用外部$ _,你可以使用" _"原型:

# dolund.pl
#
use strict;

sub dolund (_)
         { my $p1 = $_[0];
           print "passed parameter is $p1\n";
           }

dolund 12;      # prints 12

my $fred = 21;  # prints 21
dolund $fred;

$_ = 'not 12';
dolund;         # prints "not 12"

如果您愿意,可以使用$p1=~ s/foo/bar/;。我只想展示$_

的隐式传递

答案 2 :(得分:3)

local $_ = ... if @_;只会在$_本地化{@ 1}},如果该子版收到了一个参数,这意味着它不会保护来电者$_。接受争论,而这不是你想要的。

最小修复是

sub sfoobar {
   local $_ = @_ ? shift : $_;
   s/foo/bar/;
   return $_;
}

但是你可以在这一点上使用命名变量。

sub sfoobar {
   my $s = @_ ? shift : $_;
   $s =~ s/foo/bar/;
   return $s;
}

5.10+引入了_原型。

sub sfoobar(_) {
   my ($s) = @_;
   $s =~ s/foo/bar/;
   return $s;
}

5.14+介绍了s///r

sub sfoobar(_) {
   return $_[0] =~ s/foo/bar/r;
}

答案 3 :(得分:0)

我必须问 - 你究竟想在这里完成什么?

看起来你想要一个像某些内置组件一样工作的子组件。比如chomp。我认为这是不好的做法。

  • 意外的事情使代码维护更难。下一个维护代码的人永远不应该想到' wtf?'。
  • 搞乱'内置'变量 - 例如将值重新分配给$_会产生非常奇怪的后果。
  • 如果有人看到你的子程序电话,他们将不得不去看看它做了什么。这几乎是一个糟糕的子程序。

问题:$_的范围是什么?

答案:"它很复杂"因为它是全球性的,但有时它是隐含的本地化的。有时它不是变量本身,它是一个别名,通过修改它你可以改变原文。

这意味着从代码可维护性的角度来看,这只是个坏消息。

来自:http://perldoc.perl.org/perlvar.html#General-Variables

$_ is by default a global variable. However, as of perl v5.10.0, you can use a lexical version of $_ by declaring it in a file or in a block with my. Moreover, declaring our $_ restores the global $_ in the current scope. Though this seemed like a good idea at the time it was introduced, lexical $_ actually causes more problems than it solves. If you call a function that expects to be passed information via $_ , it may or may not work, depending on how the function is written, there not being any easy way to solve this. Just avoid lexical $_ , unless you are feeling particularly masochistic. For this reason lexical $_ is still experimental and will produce a warning unless warnings have been disabled. As with other experimental features, the behavior of lexical $_ is subject to change without notice, including change into a fatal error.