【问题标题】:Does my $_; do anything if $_ is implied我的 $_;如果隐含 $_ 则执行任何操作
【发布时间】:2011-03-24 12:15:02
【问题描述】:

我认为答案是肯定的,但我只是想确定一下。所以如果我有

sub something {
    my $_;
    my @array = ...;
    while ( @array ) {
        say;
    }
}

my $_; 在词法化传递给 say 的参数方面真的有效吗?

在这种特殊情况下,我使用的是DZP::UnusedVarsTests,它抱怨我没有使用my $_;,我怀疑这是一个错误,因为我在隐含的情况下使用它。

【问题讨论】:

  • 请不要那样做。我不想成为追随你并不得不弄清楚这一点的程序员,特别是因为它是对 Perl 的最新更改。为什么不创建一个临时的、命名为循环范围的变量?
  • 这个变化已经超过 2.5 年了,但是使用循环范围的变量是个好主意。
  • 我想说我刚刚编写了一个简单的示例我有一些不是循环的地方,我正在使用默认参数。
  • 据我了解,词法主题的原始实现有been deprecated。也作为另一个问题stackoverflow.com/a/28945476/2019415 的答案添加。

标签: perl lexical-scope


【解决方案1】:

简短的回答是肯定的。它使该范围内的函数使用词法范围的$_,而不是全局$_。如果他们回信给$_,就像s/// 一样,您将获得一定程度的损害控制。

perldoc perldelta (5.10.0):

List::Util::first”在出现词汇 $_(通常由“my $_”引入或由“given”隐式引入)时行为不端。为每次迭代设置的变量是包变量$_,而不是词法$_ [RT #67694]。

类似的问题可能发生在其他提供以块作为第一个参数的函数的模块中,例如

foo { ... $_ ...} list

而且,perldoc perl591delta 继续说:

词法 $_

默认变量$_ 现在可以词法化,通过声明它像 任何其他词法变量,带有 简单

     my $_;

$_ 上的默认操作将使用 $_ 的词法范围版本(如果存在),而不是全局 $_

在 "map" 或 "grep" 块中,如果 $_ 之前是 my'ed,则块内的 $_ 也是词法的(并且作用于块) .

$_ 已经词法化的作用域中,您仍然可以通过使用$::_ 访问$_ 的全局版本,或者更简单地说,使用“our $_”覆盖词法声明。

示例

我想提供一些示例来说明为什么要使用此功能:

my $_ = 'BOOM!';

sub something {
    my $_;                         ## Try running with and without
    my @array = qw/foo bar baz/;
    while ( $_ = pop @array ) {
        say;
    }   
}   

something();

say;

还有一个例子

my $_ = 'foo';

sub something {
  my $_ = $_;  ## Try running with and without
  s/foo/bar/;
  $_;
}

something();

say;

【讨论】:

  • perl591delta?啊哈!难怪my $_ 听起来很奇怪。我已经过时并且没有实践。 :(
  • 您的示例显示了如何使用此功能以及为什么不应该使用它。如果你发现自己在写我的 $_,那么你做错了什么。如果一个包需要你写我的 $_ 那么 IT 做错了什么。
  • @Matthew,如果您正在编写一个包并且您不想将所有 CORE 操作绑定到一个命名变量,您可以本地化 $_ 变量。我并不是说这是一个好主意,只是因为我并不完全相信默认变量的想法是一个的想法。当然,从最小惊喜的角度来看,基于 OO 的类型更具吸引力。
  • 我个人的看法是,除非有技术原因……所有这些特殊变量在默认情况下都应该是词法的。
  • @Ven'Tatsu, $_ 如果函数使用 _ 原型,则可以在被调用函数中进行词法访问。当函数被调用时,$_ 与任何其他参数一样被别名为@_ 的元素。试试perl -MData::Dumper -e 'sub foo(_) { print Dumper \@_ }; foo for 1..3;
猜你喜欢
  • 2023-03-09
  • 2019-07-18
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 1970-01-01
  • 2015-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多