为什么这个 Ruby 的每个循环不会停止?

4

我在我的个人项目中有以下代码:

def allocate(var, value) # Allocate the variable to the next available spot. 
  @storage.each do |mem_loc|
    if mem_loc.free?
      mem_loc.set(var, value) # Set it then break out of the loop.
      break
    end
  end
end

存储数组中的每个项目都是一个对象,它响应free?和set方法。我想做的是循环遍历数组,查找下一个空闲对象以设置变量。我的问题是,这只是循环遍历所有对象并将它们全部设置。我是否不正确地使用了break函数?

测试它,我调用以下内容:

store.allocate(:a, 10)
store.allocate(:b, 20)

所以store[1]应该被设置为:b和20。但是当我输出内容时,它的值是10,数组中其余部分也是如此。


它在Ruby 1.9.2dev上运行良好。我刚测试过。我不确定Ruby 1.8.x是否可行。 - Daniel O'Hara
@floatless nums.each {|x| if (x % 2 == 0) then puts "#{x} 是偶数"; break; end } 在 Ruby 1.8.7 上运行良好。 - Telemachus
如果我理解正确的话,您想遍历数组直到找到第一个自由对象,设置它,然后停止。对吗?实际上正在发生的是每个(?)项目都通过了free?测试并被设置,但是each循环从未中断?是这样吗? - Telemachus
2
使用 find 替代 each/if/break:@storage.find(&:free?).set(var,value) - Lars Haugseth
1个回答

2

我相信我已经找到了错误,实际上它并不在上面的代码中。当我设置存储数组时,我是这样做的:

@storage = [Memory_location.new] * 1000

相信它会创建1000个不同的对象。实际上发生的是,它创建了1000个相同对象的引用,所以当我改变其中一个时,所有的都被改变了。我可以通过在两个不同的数组位置使用puts方法来证明这一点,两个位置都返回:

#{Memory_location:0x2bc8b74}

1
请尝试使用1000.times { @storage << Memory_location.new } - Telemachus
3
实际上,有一种通过传递块来创建新对象的方法。 @storage = Array.new(1000){ MemoryLocation.new } - Chubas
2
另一种方法是:@storage = (1..1000).map { MemoryLocation.new } - Lars Haugseth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接