Почему очистка моего хэша также очищает мой массив хэшей? - PullRequest
3 голосов
/ 21 марта 2011
ruby-1.9.2-p180 :154 > a = []
 => []
ruby-1.9.2-p180 :154 > h = {:test => "test"}
 => {:test=>"test"} 
ruby-1.9.2-p180 :155 > a << h
 => [{:test=>"test"}] 
ruby-1.9.2-p180 :156 > h.clear
 => {} 
ruby-1.9.2-p180 :157 > a
 => [{}] 

Я очень запутался, тем более что я могу изменять элементы хэша, не влияя на массив. Но когда я очищаю хеш, массив обновляется и очищается от его хеш-содержимого. Может кто-нибудь объяснить?

Ответы [ 2 ]

5 голосов
/ 21 марта 2011

Когда вы делаете a << h, вы действительно передаете ссылку h на a. Поэтому, когда вы обновляете h, a также видит эти изменения, потому что он содержит ссылку, а не копию этого значения.

Чтобы оно не изменилось в a, вы должны передать клонированное значение h в a.

Примером может быть:

a << h.clone
1 голос
/ 21 марта 2011

Ruby не создает копию этого хэша при добавлении его в массив - он просто сохраняет ссылку на исходную переменную.Итак, когда вы очищаете исходную переменную, ссылка, хранящаяся в массиве, теперь ссылается на пустой хеш.

Если вы хотите скопировать элемент хеша, чтобы этого не произошло, используйте метод clone Руби.

ruby-1.9.2-p136 :049 > h = { :test => 'foo' }
 => {:test=>"foo"}
ruby-1.9.2-p136 :050 > a = []
 => [] 
ruby-1.9.2-p136 :051 > a << h.clone
 => [{:test=>"foo"}] 
ruby-1.9.2-p136 :052 > h.clear
 => {} 
ruby-1.9.2-p136 :053 > a
 => [{:test=>"foo"}] 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...