4 ms·
I basically gave up on perl after discovering this: foo foreach @bar; sub foo { s/foo/bar/ print; } This clobbers the content of @bar due to mu
by joeyh 15y ago
I basically gave up on perl after discovering this:
foo foreach @bar;
sub foo {
s/foo/bar/
print;
}
This clobbers the content of @bar due to mutating the $_ variable.
Which is a useful feature. But imagine that foo, instead of directly mutating the value passed to it, calls into a complex set of other code. Now you have a bomb where working code can break in crazy ways if any of it gets changed to modify $_.
Having to audit code for this kind of thing is a real pain. I still maintain existing perl projects, but won't be starting any new ones.
- prakashk 15y agoThis is not much different than mutating a global variable inside a function. I would write your code as: foo($_) foreach @bar; sub foo { my $var = shift; $var =~ s/foo/bar/; print $var; } You can also fix this is to localize $_ inside the function, if you don't want to pass $_ as a parameter. foo foreach @bar; sub foo { my $var = $_; $var =~ s/foo/bar/; print $var; } You can even use $_ instead of $var (although it looks a little weird assigning $_ to itself): foo foreach @bar; sub foo { my $_ = $_; s/foo/bar/; print; }
- pavelkaroukin 15y agoThis is a feature, not a bug. And this is not _requirement_, it is up to you to use it. You are always free to pass parameters the way it would not happen..
- grout 15y agoYou're funny. If this really pushed you over the edge, you were born -on- the edge, and didn't give Perl a fair shake.
- ccashell 15y agoI think it's a pretty weak reason to give up on a language because you were using a global variable and expecting it to automatically be treated as a local variable within your function. As others have mentioned, you are using a global variable ($_) inside a function. This is generally considered a bad practice. The standard perl idiom of getting your function arguments via shift would make this a non-issue.