在Perl中声明循环内部或外部的变量,最佳实践

cal*_*llo 5 perl variable-declaration

我一直在研究一些用于数据挖掘的Perl库.这些库充满了嵌套循环,用于收集和处理信息.我正在使用严格模式,我总是my在第一个循环之外声明我的变量.例如:

# Pretty useless code for clarity purposes:

my $flag = 1;
my ($v1, $v2);

while ($flag) {
  for $v1 (1 .. 1000) {

    # Lots and lots of code...

    $v2 = $v1 * 2;
  }
}
Run Code Online (Sandbox Code Playgroud)

对于我在这里阅读的内容,性能方面,最好在循环之外声明它们,然而,我的代码的维护变得越来越困难,因为一些变量的声明最终远离它们实际上的位置用过的.

像这样的东西会更容易保持:

my $flag = 1;

while ($flag) {
  for my $v1 (1 .. 1000) {

    # Lots and lots of code...

    my $v2 = $v1 * 2;
  }
}
Run Code Online (Sandbox Code Playgroud)

我没有太多的Perl经验,因为我来自主要使用C++.在某些时候,我想开源我的大多数库,所以我希望它们尽可能地满足所有Perl大师的需求.

从专业的Perl开发人员的角度来看,这些选项之间最合适的选择是什么?

Bor*_*din 15

一般规则是尽可能地声明每个变量.

如果变量的值不需要在循环的迭代中保持,则在循环声明它,或者作为循环的循环控制变量for.

如果它需要在循环迭代中保持静态(比如你的$flag),那么在循环之前立即声明它.

是的,如果每次执行一个块时丢弃并重新分配变量,则需要支付最低的速度成本,但编程和维护成本是迄今为止最重要的效率,应始终放在首位.

在使代码工作并且发现运行速度太慢之前,您不应该优化代码; 即便如此,将声明移动到文件的顶部仍然是可能产生有用差异的妥协列表的很长一段路.


amo*_*mon 5

优化可读性。这意味着在尽可能小的范围内声明变量。理想情况下,我可以同时看到变量声明和该变量的所有用法。我们只能在脑海中保留非常有限的上下文,因此在变量使用附近声明变量可以更容易理解、编写和调试代码。

了解哪个变体表现更好很难估计,也很难衡量,因为效果会相当小。但如果性能大致相当,我们不妨使用更具可读性的变体。

我个人经常尝试以不重新分配变量的单一赋值形式编写代码,并且push @array, $elem避免使用类似的变异器。这确保变量的名称及其值始终可以互换,从而更容易推理代码。这意味着每个变量声明也是一个初始化,它消除了一整类错误。

  • @calvillo:amon 的意思是他从不*改变*变量的值。如果需要从变量派生的值,则他使用新变量。但我不明白这如何处理数组和哈希等聚合变量。分配整个数组并且从不更改它似乎不切实际,除非明智地使用`map`,这很容易混淆代码的目的。 (2认同)