使用"for"对变量进行局部化显然很糟糕.为什么?

Ger*_*ard 2 perl scalar

所以我回答了一个关于SO的问题,并为此得到了很多抨击.我已经使用Perl很多年了,并且非常多地使用这个主题.

所以让我们从一些代码开始吧.我在这些例子中进行搜索和替换.我们的想法是搜索onethree从两个字符串中搜索并替换它们.

$values = 'one two three four five';
$value2 = 'one 2 three four 5';

$values =~ s/one//g;
$values =~ s/three//g;

$values2 =~ s/one//g;
$values2 =~ s/three//g;
Run Code Online (Sandbox Code Playgroud)

这段代码很简单,每个人都接受它.

我还可以构建一个数组或散列,其中包含要搜索和替换的值列表,这也是可以接受的.

但是,当我构建一个脚本来进行话题化$values$values2减少构建脚本的键入量时,它似乎被误解了?

这是代码.

$values = 'one two three four five';
$value2 = 'one 2 three four 5';

for ( $values, $values2 ) {
    s/one//g;
    s/three//g;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码将讨论for块的持续时间的变量,但许多程序员反对这一点.我想明白为什么这是不可接受的?

mel*_*ene 6

有几点需要考虑.


您的代码在变量列表上执行多个替换.你可以不用使用$_:

for my $s ($values, $values2) {
    $s =~ s/one//g;
    $s =~ s/three//g;
}
Run Code Online (Sandbox Code Playgroud)

我个人认为上面的代码没有错.

一般的问题$_是它不是局部变量.例如,如果你的for循环体调用一个函数(调用一个函数......)$_而不进行本地化修改(例如通过赋值或使用裸s///或使用while (<...>)),那么它将覆盖你正在迭代的变量.使用my变量,您将受到保护,因为其他函数无法查看您的局部变量.

也就是说,如果你的其余代码没有这个错误(在$_没有本地化的情况下涂鸦),那么$_在这里工作正常.


但是,你最初抱怨的答案中的代码是不同的:

for ($brackets) {
    s/\\left/(/g;
    s/\\right/)/g;
}
Run Code Online (Sandbox Code Playgroud)

在这里,你不是要对许多变量进行相同的替换; 你只是通过摆脱部分来节省一些打字$brackets =~:

$brackets =~ s/\\left/(/g;
$brackets =~ s/\\right/)/g;
Run Code Online (Sandbox Code Playgroud)

使用显式循环变量不是解决方案,因为您仍然需要$foo =~在每一行输出.

这更像是品味问题.您只是for用于其别名效果,而不是循环多个值.我个人对此仍然很好.

  • 在答案中使用`for`的方式让我想起了像Visual Basic这样的语言,其中有一个[`with`block](https://docs.microsoft.com/en-us/dotnet/articles/visual-basic/language-reference/statements/with-end-with-statement)(这是.net,我的意思是VB5但找不到它).[JavaScript也有](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/with).Perl中的`for`循环可以用来做同样的事情,但正如melpomele所说,它带有副作用,实现其他语言的实现就是没有. (2认同)