为什么我的块只执行一次?

joh*_*mue 2 ruby

为什么:

array = (1..20).to_a
array.index.each_slice(5) do |slice|
  puts slice.inspect
end
Run Code Online (Sandbox Code Playgroud)

收益:

[1, 2, 3, 4, 5]
[6, 7, 8, 9, 10]
[11, 12, 13, 14, 15]
[16, 17, 18, 19, 20]
Run Code Online (Sandbox Code Playgroud)

而:

other_array = []
array = (1..20).to_a
array.index.each_slice(5) do |slice|
  puts slice.inspect
  other_array.push(1)
end
Run Code Online (Sandbox Code Playgroud)

仅返回:

[1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)

如何other_array.push(1)打破块的执行?一个明显的结论是我无法访问不在块范围内的变量,但为什么会这样?

0xA*_*ffe 6

我在阵列文档中找到了解决方案.我想知道为什么你index似乎只想迭代数组时使用该函数的数组.为此,您可以在array.each_slice不调用索引的情况下使用.指数表示如下:http://ruby-doc.org/core-2.2.0/Array.html#method-i-index

返回ary中第一个对象的索引,使对象为== to obj.

如果给出一个块而不是一个参数,则返回该块返回true的第一个对象的索引.如果未找到匹配项,则返回nil

所以你的代码会评估块并检查结果是否正确true.在第一个例子中,你只puts返回一个nil.没错是假的.
第二个示例返回包含单个1的数组的对象.
在ruby中,每个条件都是true,如果不是false或者nil.你可以在这里看到:

if nil
   puts "foo"
end
=> nil

other_array = [1]
if other_array
  puts "foo"
end
=> "foo"
Run Code Online (Sandbox Code Playgroud)

因此,在你的第二个例子中,块返回的东西不假,所以它不会再次运行,因为它找到了一个"有效"的结果.

对于返回,您可能应该知道ruby返回任何范围中的最后一个表达式,如果没有给出其他返回值.所以它回来了other_array.如果您不想重新格式化代码,可以执行以下操作:

other_array = []
array = (1..20).to_a
array.index.each_slice(5) do |slice|
  puts slice.inspect
  other_array.push(1)
  nil 
end
Run Code Online (Sandbox Code Playgroud)

这将强制块返回nil,迭代将起作用.