I am trying to do something like this in a ruby module:
def initialize
super
@@main_array = Array.new(16) { Array.new}
end
def add_hash(hash={})
@@main_array[get_id] << hash
end
# Where get_id returns 0-15
I expect each sub-array to have only the hashes that were added to it. Instead, all sub-arrays have all hashes added. Inspecting the array shows that the sub-arrays all share object ID's.
I'm not sure why this is the case. What am I missing here?
Edit:
Here's the exact code I'm using:
module Manager
def initialize
super
@@main_array = Array.new(BaseCompany.get_number_thread(), Array.new())
end
def self.check_and_add_thread_activity(activity={})
action = Hash.new
action[:id] = @@main_array[BaseCompany.get_current_threadid].length +1
action[:name] = activity[:name]
action[:added] = true
@@main_array[BaseCompany.get_current_threadid] << action
return action
end
end
Check_and_add is called by other parts of the code, as the individual threads execute functionality
Okay, I've actually solved it. In the comments below someone mentioned that this:
Array.new(16,Array.new)
Would cause the sub-arrays to have the same object ID. Someone else corrected him saying it shouldn't happen, but this was the case in my code. I replaced that line with the recommended:
Array.new(16) {Array.new}
And this worked just fine.
For reference, I'm using JRuby 1.7.3
main_array = Array.new(16, Array.new)
is equivalent to :
row = Array.new
main_array = Array.new(16,row)
or just
main_array = [row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row]
So you have 16 times exactly the same object (one empty Array). Modifying one element will automatically modifiy all the others :
p main_array
#=> [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
row << 1
p main_array
#=> [[1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]
main_array = Array.new(16){ Array.new }
is equivalent to :
main_array = (1..16).map{ Array.new }
or :
main_array = [Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new, Array.new]
Now you have 16 empty Arrays, but they are all different objects. Modifying one element won't modify any of the other arrays :
main_array = Array.new(16){ Array.new }
p main_array
#=> [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
main_array[0] << 1
p main_array
#=> [[1], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.