У меня есть сомнения, что в ruby ​​все ли объекты в ruby ​​проходят или присваивают значение по ссылке. Потому что, когда я попытался присвоить переменную экземпляра локальному. Изменения, внесенные в локальные изменения, также влияют на переменную экземпляра.

Вот мой код.

@name = {:a=> 'sfgs', :b=> 'sdfsd'}
name = @name
name.except!(:a) 

Когда я печатаю @name, пара ключ-значение :a была удалена. Если да, то любым другим способом предотвратить это. i.e Копирование переменной экземпляра без ссылки.

0
Mr Movies Tamil 23 Окт 2019 в 14:59
Ruby — это передача по значению/копированию. Но в случае сложных объектов исходное значение и его копия являются ссылками на объект где-то еще.
 – 
Sergio Tulentsev
23 Окт 2019 в 15:03
Эмпирическое правило: никогда не используйте изменяющие методы.
 – 
Aleksei Matiushkin
23 Окт 2019 в 15:04
@AlekseiMatiushkin: иногда приходится по соображениям производительности. Но да, это хорошее правило по умолчанию
 – 
Sergio Tulentsev
23 Окт 2019 в 15:05
Не с тобой, почему? В целом.
 – 
Aleksei Matiushkin
23 Окт 2019 в 15:09
Кстати, Hash#except! действителен ruby? Какая версия?
 – 
Aleksei Matiushkin
23 Окт 2019 в 15:10

1 ответ

Вам нужно deep copy. Попробуй это:

name = Marshal.load(Marshal.dump(@name))

name.except!(:a)
p name
#=> { :b => "sdfsd" }
p @name
#=> { :a => "sfgs", :b => "sdfsd" }
0
demir 23 Окт 2019 в 15:01
1
Или просто не используйте мутирующий except!
 – 
Sergio Tulentsev
23 Окт 2019 в 15:03
2
Здесь @name.dup будет достаточно.
 – 
Aleksei Matiushkin
23 Окт 2019 в 15:06
@AlekseiMatiushkin: пока кто-нибудь не решит исказить значения :)
 – 
Sergio Tulentsev
23 Окт 2019 в 15:07
2
«здесь» — ключевое слово. Очевидно, я знаю, как работает dup :-P
 – 
Aleksei Matiushkin
23 Окт 2019 в 15:09