开发者

In Ruby, why does Array.new(size, object) create an array consisting of multiple references to the same object?

开发者 https://www.devze.com 2023-02-03 13:50 出处:网络
As mentioned in this answer, Array.new(size, object) creates an array with size refer开发者_开发问答ences to the same object.

As mentioned in this answer, Array.new(size, object) creates an array with size refer开发者_开发问答ences to the same object.

hash = Hash.new
a = Array.new(2, hash)
a[0]['cat'] = 'feline'
a # => [{"cat"=>"feline"},{"cat"=>"feline"}]
a[1]['cat'] = 'Felix'
a # => [{"cat"=>"Felix"},{"cat"=>"Felix"}]

Why does Ruby do this, rather than doing a dup or clone of object?


Because that's what the documentation says it does. Note that Hash.new is only being called once, so of course there's only one Hash

If you want to create a new object for every element in the array, pass a block to the Array.new method, and that block will be called for each new element:

>> a = Array.new(2) { Hash.new }
=> [{}, {}]
>> a[0]['cat'] = 'feline'
=> "feline"
>> a
=> [{"cat"=>"feline"}, {}]
>> a[1]['cat'] = 'Felix'
=> "Felix"
>> a
=> [{"cat"=>"feline"}, {"cat"=>"Felix"}]


For certain classes that can't be modified in-place (like Fixnums) the Array.new(X, object) form works as expected and is probably more efficient (it just calls memfill instead of rb_ary_store and yielding to the block):

For more complicated objects you always have the block form (e.g. Array.new(5) { Hash.new }).

*Edit:* Modified according to the comments. Sorry for the stupid example, I was tired when I wrote that.


I came up with this answer, very short and simple solution

c_hash = Hash.new
["a","b","c","d","e","f"].each do |o|
  tmp = Hash.new
  [1,2,3].map {|r| tmp[r] = Array.new}
  c_hash[o] = tmp
end
c_hash['a'][1] << 10
p c_hash
0

精彩评论

暂无评论...
验证码 换一张
取 消