Ruby for循环陷阱?

Bor*_*cky 16 ruby

在对Ruby循环的讨论中,与每个循环相比,Niklas B.最近谈到了循环"不引入新范围".我想看一些人们如何看待这个问题的例子.

好吧,我扩展了一个问题:在Ruby的其他地方我们看到了什么apears做/结束块分隔符,但实际上里面没有范围?还有什么别的...做...结束?

好的,问题的另一个扩展,是否有办法用花括号{block}编写循环?

Nik*_* B. 14

让我们通过一个例子说明这一点:

results = []
(1..3).each do |i|
  results << lambda { i }
end
p results.map(&:call)  # => [1,2,3]
Run Code Online (Sandbox Code Playgroud)

很酷,这是预期的.现在检查以下内容:

results = []
for i in 1..3
  results << lambda { i }
end
p results.map(&:call)  # => [3,3,3]
Run Code Online (Sandbox Code Playgroud)

嗯,发生了什么事?相信我,这些类型的错误是令人讨厌的追踪.Python或JS开发人员会知道我的意思:)

仅仅这一点是我避免像瘟疫这样的循环的原因,尽管有更多有利于这一立场的好论据.正如Ben指出的那样,使用正确的方法Enumerable几乎总是会导致比使用普通的旧的命令式for循环或发烧友更好的代码Enumerable#each.例如,上面的例子也可以简洁地写成

lambdas = 1.upto(3).map { |i| lambda { i } }
p lambdas.map(&:call)
Run Code Online (Sandbox Code Playgroud)

我扩展了一个问题:在Ruby的其他地方我们看到了什么apears做/结束块分隔符,但实际上里面没有范围?还有什么别的...做...结束?

每个循环结构都可以这样使用:

while true do
  #...
end

until false do
  # ...
end
Run Code Online (Sandbox Code Playgroud)

另一方面,我们可以在没有do(这显然是可取的)的情况下编写其中的每一个:

for i in 1..3
end

while true
end

until false
end
Run Code Online (Sandbox Code Playgroud)

问题的另一个扩展是,有一种方法可以用花括号{block}来编写循环

不,那里没有.还要注意术语"块"在Ruby中具有特殊含义.

  • 我也会对此进行扩展(很棒的答案,Niklas B.).永远不要说永远,但我*永远*写*也不想在Ruby代码中看到`for`循环.它们根本不是惯用语,它们为不知情的开发人员引入了令人讨厌的陷阱.使用[`Enumerable`](http://ruby-doc.org/core-1.9.3/Enumerable.html)提供的内容. (3认同)