当以下代码可能有副作用?
@some = map { s/xxx/y/; $_ } @some;
Run Code Online (Sandbox Code Playgroud)
perlcritic解释它是危险的,因为例如:
@other = map { s/xxx/y/; $_ } @some;
Run Code Online (Sandbox Code Playgroud)
和成员@someGOT 也修改.了解.我有BPB书,它通过示例显示了上面的内容
@pm_files_without_pl_files
= grep { s/.pm\z/.pl/xms && !-e } @pm_files;
Run Code Online (Sandbox Code Playgroud)
我还阅读了" 列表处理副作用 " 一章/" 绝不修改列表函数中的$ _ ".及其粉丝.我也知道/r.
要明确(尽管我可怕的英语很可能):
在第一个例子中,要点是修改原件@some.
问题是:
@some = map { s/xxx/y/; $_ } @some; 导致一些不必要的副作用吗?如果是,何时?正在寻找答案,因为一些"perl初学者的书" - 因此仍然不接受任何当前的答案.;)
Leo*_*ans 11
perl的一个箴言一直是TIMTOWTDI:有不止一种方法可以做到这一点.如果两种方式具有相同的最终结果,则它们同样正确.这并不意味着没有理由偏向另一种方式.
在第一种情况下,对我来说,更明显(对我来说,YMMV)
s/xxx/y/ for @some;
Run Code Online (Sandbox Code Playgroud)
这主要是因为它的沟通意图更好.for表明这是副作用的全部,而map暗示它是关于返回值.虽然在功能上完全相同,但对于您的同事程序员来说这应该更容易理解(并且可能在6个月内为您自己).
有不止一种方式,但有些方法比其他方式更好.
代码就像你的例子:
@some = map { s/xxx/y/; $_ } @some;
Run Code Online (Sandbox Code Playgroud)
应该避免,因为它是多余的和令人困惑的.它看起来像左边的分配应该做的事情,尽管它实际上是一个无操作.的确,只写:
map { s/xxx/y/; $_ } @some;
Run Code Online (Sandbox Code Playgroud)
会产生完全相同的效果,如:
map { s/xxx/y/ } @some;
Run Code Online (Sandbox Code Playgroud)
这个版本至少具有使(合理地)明确map忽略返回值的优点,并且声明的实际目的是@some在适当的位置进行修改.
但是,正如莱昂已经指出的那样,到目前为止,最清晰,最惯用的写作方式是:
s/xxx/y/ for @some;
Run Code Online (Sandbox Code Playgroud)