tags:

views:

78

answers:

1

I have the following code in one of my personal projects:

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

Each item in the storage array is an object that responds to free? and set. What I am trying to do is cycle through the array, looking for the next free (empty) object to set the variable to. My problem is, this just cycles through every object and sets them all. Am I using the break function incorrectly?

Testing it, I call the following:

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

So store[1] should be set to :b and 20. But when I output the contents, it's value is 10, as is the rest of the array.

A: 

I believe I have found the mistake, and it wasn't actually in the code above. When I set up the storage array, I did like so:

@storage = [Memory_location.new] * 1000

Believing it would create 1000 different objects. What I think actually happened, was that it created 1000 references to the same object, so when I changed one of them, I changed all of them. I could prove this by using the puts method on two different array locations, with both of them returning:

#{Memory_location:0x2bc8b74}
bennybdbc
Try `1000.times { @storage << Memory_location.new }` instead.
Telemachus
Yes that works perfectly. Thanks Telemachus.
bennybdbc
Actually, there's a way to create new objects, passing a block. `@storage = Array.new(1000){ MemoryLocation.new }`
Chubas
Yet another way: `@storage = (1..1000).map { MemoryLocation.new }`
Lars Haugseth