所以I answered a question on SO and got a lot of flack for it。 我已经使用Perl很多年了,并且非常多地使用它。
所以让我们从一些代码开始吧。我在这些例子中进行搜索和替换。我们的想法是从两个字符串中搜索one
和three
并替换它们。
$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;
此代码很简单,每个人都接受它。
我还可以构建一个数组或散列,其中包含要搜索和替换的值列表,这也是可以接受的。
但是,当我构建一个脚本以显示$values
和$values2
并减少构建脚本的输入量时,它似乎被误解了?
这是代码。
$values = 'one two three four five';
$value2 = 'one 2 three four 5';
for ( $values, $values2 ) {
s/one//g;
s/three//g;
}
上面的代码将在for
块的持续时间内将变量局部化,但许多程序员都反对这一点。我想明白为什么这是不可接受的?
答案 0 :(得分:6)
有几点需要考虑。
您的代码在变量列表上执行多次替换。您可以在不使用$_
的情况下执行此操作:
for my $s ($values, $values2) {
$s =~ s/one//g;
$s =~ s/three//g;
}
我个人认为上述代码没有任何问题。
$_
的一般问题是它不是局部变量。例如。如果for
循环的主体调用一个函数(调用一个函数......)修改$_
而不进行本地化(例如通过分配它或使用裸s///
或使用它while (<...>)
),然后它将覆盖你正在迭代的变量。使用my
变量,您将受到保护,因为其他函数无法查看您的局部变量。
也就是说,如果你的其他代码没有这个错误(在没有本地化的情况下涂鸦$_
),$_
在这里可以正常工作。
然而,你最初抱怨的答案中的代码是不同的:
for ($brackets) {
s/\\left/(/g;
s/\\right/)/g;
}
在这里,您不是要尝试对许多变量执行相同的替换;你只是通过摆脱$brackets =~
部分来节省一些打字:
$brackets =~ s/\\left/(/g;
$brackets =~ s/\\right/)/g;
使用显式循环变量不是解决方案,因为您仍然需要在每一行输出$foo =~
。
这更多的是品味问题。您只使用for
进行别名效果,而不是循环使用多个值。就个人而言,我对此仍然很好。
答案 1 :(得分:4)
foreach是设置局部化器的非实验性方法。
OP的构造是编写Perl代码的完美有效方式。我对其早期答案的唯一要点是
与此处的示例不同,只有两个操作应用于单个变量。这只是简单地比简单地写两个替换更简单,我不会在这里打扰,虽然我可能考虑
s/one//g, s/three//g for $value;
除了topicaliser之外,答案与已发布的另一个答案相同。我不相信这会使其与另一篇文章有足够的不同