Topicalising a variable using “for” is apparently bad. Why?

无人久伴 提交于 2019-12-12 10:12:57

问题


So I answered a question on SO and got a lot of flack for it. I have been using Perl for many years and use this topicalising quite a lot.

So let's start with some code. I am doing search and replace in these examples. The idea is to search for one and three from two strings and replace them.

$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;

This code is simple and everyone accepts it.

I can also build an array or hash with a list of values to search and replace which is also acceptable.

However, When I build a script to topicalise $values and $values2 and lessen the amount of typing to build a script it seems to be misunderstood?

Here is the code.

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

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

The above code will topicalise the variables for the duration of the for block, but many programmers are against this. I want to understand why this is unacceptable?


回答1:


perldoc perlsyn has this

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

The OP's construct is a perfectly valid way of writing Perl code. The only provisons I have regarding their earlier answer are

  • Unlike the example here, only two operations were being applied to a single variable. That is only marginally briefer than simply writing two substitutions and I wouldn't bother here, although I may consider

    s/one//g, s/three//g for $value;
    
  • Other than the topicaliser, the answer is identical to another one already posted. I don't believe this makes it sufficiently different to warrant another post




回答2:


There are several points to consider.


Your code performs multiple substitutions on a list of variables. You can do that without using $_:

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

Personally I think nothing is wrong with the above code.

The general problem with $_ is that it's not a local variable. E.g. if the body of your for loop calls a function (that calls a function ...) that modifies $_ without localizing it (e.g. by assigning to it or using a bare s/// or using while (<...>)), then it will overwrite the variables you're iterating over. With a my variable you're protected because other functions can't see your local variables.

That said, if the rest of your code doesn't have this bug (scribbling over $_ without localizing it), $_ will work fine here.


However, the code in your answer people originally complained about is different:

for ($brackets) {
    s/\\left/(/g;
    s/\\right/)/g;
}

Here you're not trying to perform the same substitutions on many variables; you're just saving yourself some typing by getting rid of the $brackets =~ part:

$brackets =~ s/\\left/(/g;
$brackets =~ s/\\right/)/g;

Using an explicit loop variable wouldn't be a solution because you'd still have to type out $foo =~ on every line.

This is more a matter of taste. You're only using for for its aliasing effect, not to loop over multiple values. Personally I'm still OK with this.



来源:https://stackoverflow.com/questions/44082720/topicalising-a-variable-using-for-is-apparently-bad-why

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!