使用"为"表示变量。显然很糟糕。为什么?

时间:2017-05-20 06:35:19

标签: perl scalar

所以I answered a question on SO and got a lot of flack for it。 我已经使用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块的持续时间内将变量局部化,但许多程序员都反对这一点。我想明白为什么这是不可接受的?

2 个答案:

答案 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)

perldoc perlsyn有此

  

foreach是设置局部化器的非实验性方法。

OP的构造是编写Perl代码的完美有效方式。我对其早期答案的唯一要点是

  • 与此处的示例不同,只有两个操作应用于单个变量。这只是简单地比简单地写两个替换更简单,我不会在这里打扰,虽然我可能考虑

    s/one//g, s/three//g for $value;
    
  • 除了topicaliser之外,答案与已发布的另一个答案相同。我不相信这会使其与另一篇文章有​​足够的不同