Perl 使用“主题化”对变量进行主题化;至于;这显然很糟糕。为什么?

Perl 使用“主题化”对变量进行主题化;至于;这显然很糟糕。为什么?,perl,scalar,Perl,Scalar,所以。 我已经使用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;

所以。 我已经使用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
块的
期间主题化变量,但许多程序员反对这一点。我想知道为什么这是不可接受的?

有几个要点要考虑。


代码对变量列表执行多个替换。您可以不使用
$\uu
来执行此操作:

for my $s ($values, $values2) {
    $s =~ s/one//g;
    $s =~ s/three//g;
}
我个人认为上面的代码没有问题

$的一般问题是它不是局部变量。例如,如果
for
循环的主体调用了一个函数(调用函数…),该函数修改了
$\u
,而没有对其进行本地化(例如,通过分配给它或使用裸
s///
或使用
while()
),那么它将覆盖您正在迭代的变量。使用
my
变量可以保护您,因为其他函数看不到您的局部变量

这就是说,如果您的其余代码没有这个bug(在
$\uu
上涂鸦而不进行本地化),
$\u
在这里可以正常工作


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

for ($brackets) {
    s/\\left/(/g;
    s/\\right/)/g;
}
在这里,你没有试图对许多变量执行相同的替换;通过去掉
$方括号=~
部分,您只需省去一些输入:

$brackets =~ s/\\left/(/g;
$brackets =~ s/\\right/)/g;
使用显式循环变量不是一个解决方案,因为您仍然需要在每一行上键入
$foo=~

这更多的是品味问题。您仅使用
for
获得其别名效果,而不是在多个值上循环。就我个人而言,我还是可以接受的。

有这个

foreach是设置局部激化剂的非实验性方法

OP的构造是编写Perl代码的一种非常有效的方法。关于他们先前的回答,我仅有的条件是

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

  • 除了主题化者,答案与另一个已经发布的答案相同。我不相信这会使它有足够的不同,以保证另一个职位


嗯。首先,通过改变现状,你的生活有点边缘化,但这本身当然不是问题。这样的代码很容易演变成维护人员的陷阱;这是个问题。您所展示的示例并没有为您节省那么多,也没有其他方法那么清晰。然而,我毫不犹豫地为@ary做
s/$patt/$repl/for
,而这正是需要做的。我的.02我找到了你的答案并把它联系起来了。两件事:只有一个人不喜欢它,其中的代码与您在这里发布的代码不同。我同意主要的方面是它让维护人员感到困惑。如果我在
$work
的代码库中遇到这段代码,我会重构它。谢谢@simbabque。你们帮我证实了我的想法:)@zdim:“这样的代码很容易演变成维护人员的陷阱”那么,你是使用
$\uuu
的反对者吗?否则我看不到你的p;oint?答案中使用的
for
的方式让我想起了像Visual Basic这样的语言,其中有一个(这是.net,我指的是VB5,但找不到它)。Perl中的
for
循环也可以用来做同样的事情,但正如Melpome所说,它带来的副作用是其他语言的实现所没有的。谢谢大家!我有我的答案。“我个人认为上面的代码没有问题”和*“我个人仍然同意”*你是说你对OP使用
$的版本感到不舒服,并且认为需要明确提及控制变量或对象变量本身?我对($text)的
有问题{s/\\left/(/g;s/\\right/)/g;}
是正则表达式引擎的两种用法!我会使用
my%括号=(左=>“(”,右=>”)$text=~s/\\(左|右)/$方括号{$1}/g
@GerhardBarnard:看来,在我对你的诽谤者说了一句话,并向主持人提出了问题之后,你的负面评论消失了,你又获得了一张反对票。干得好。最后的报价是怎么回事?我试着修好它。不确定是否更好。@simbabque:A
而不是
-
!谢谢
s/one//g, s/three//g for $value;