Клонировать константу хэша в новую переменную без изменения константы при обновлении с помощью блока .each? - PullRequest
0 голосов
/ 03 мая 2018

Я борюсь с чем-то. Я абстрагировал свой код так, чтобы он был максимально простым, но я до сих пор не понимаю, почему у него такое поведение.

Я создаю константу, состоящую из набора пар ключ-значение, и замораживаю ее. Затем я использую метод .dup, чтобы скопировать хеш в новую переменную.

Однако, когда я перебираю массив и пытаюсь сохранить его в (ранее пустом) массиве в новой переменной, он обновляет не только новую переменную, но и исходную константу. Это, кажется, имеет место только с методом .each - если я передаю новые значения непосредственно как новый массив, он работает без обновления константы.

Ниже приведен мой обобщенный код:

CONFIG_VALUES = { results: [], loop_count: 0 }.freeze
the_results = ["foo", "bar"]
abc = CONFIG_VALUES.dup
the_results.each do |res| 
  abc[:results] << res
end
abc
#=> {:results=>["foo", "bar"], :loop_count=>0}
CONFIG_VALUES
#=> {:results=>["foo", "bar"], :loop_count=>0}

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Вы можете достичь желаемого результата с помощью:

CONFIG_VALUES = { results: [], loop_count: 0 }.freeze
the_results = %w[foo bar]

abc = CONFIG_VALUES.merge(results: the_results)

abc
#=> {:results=>["foo", "bar"], :loop_count=>0}
CONFIG_VALUES
#=> {:results=>[], :loop_count=>0}

Насколько я понимаю, это работает, потому что #merge не мутирует CONFIG_VALUES и вы по сути создаете совершенно новый набор объектов.

0 голосов
/ 03 мая 2018

Hash#dup метод не рекурсивный. В любом случае, если вы используете Ruby on Rails, и я думаю, что вы используете, так как вы пометили его, вы можете использовать метод #deep_dup: http://api.rubyonrails.org/classes/Hash.html#method-i-deep_dup

Это метод ActiveSupport, так что вы можете просто использовать гем, если вы не используете Ruby on Rails.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...