使用 "for" 对变量进行主题化显然是不好的。为什么?

Topicalising a variable using "for" is apparently bad. Why?

所以。 我已经使用 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;

这个代码很简单,大家都接受。

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

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

这是代码。

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

for ( $values, $values2 ) {
    s/one//g;
    s/three//g;
}

上面的代码将在 for 块的持续时间内对变量进行主题化,但许多程序员反对这样做。我想了解为什么这是不可接受的?

有几点需要考虑。


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

的情况下做到这一点
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 来获得别名效果,而不是循环使用多个值。就我个人而言,我仍然可以接受。

perldoc perlsyn 有这个

The foreach is the non-experimental way to set a topicalizer.

OP 的构造是编写 Perl 代码的完全有效的方式。我对他们之前的回答唯一的限制是

  • 与这里的例子不同,只有两个操作被应用于一个变量。这只比简单地写两个替换稍微简短一点,我不会在这里打扰,尽管我 可能 考虑

    s/one//g, s/three//g for $value;
    
  • 除了主题词,答案与另一个已经 post 的答案相同。我认为这不足以保证另一个 post