Неожиданная ошибка FrozenError при добавлении элементов через << - PullRequest
0 голосов
/ 14 мая 2019

У меня есть хэш, содержащий имена и категории:

hash = {
  'Dog' => 'Fauna',
  'Rose' => 'Flora',
  'Cat' => 'Fauna'
}

и я хочу реорганизовать его так, чтобы имена были сгруппированы по соответствующей категории:

{
  'Fauna' => ['Dog', 'Cat'],
  'Flora' => ['Rose']
}

Я добавляю каждое имя через <<:

new_hash = Hash.new
hash.each do |name , category|
  if new_hash.key?(category)
    new_file[category] << name 
  else
    new_hash[category] = name
  end    
end

Но мне говорят, что эта операция выполняется для замороженного элемента:

`<< ': невозможно изменить замороженную строку (FrozenError) </p>

Я полагаю, это потому, что each дает замороженные объекты. Как я могу реструктурировать этот код, чтобы «.each» не предоставлял замороженные переменные?

Ответы [ 2 ]

2 голосов
/ 14 мая 2019

Мне нужно было добавить имя в массив, а затем этот массив в хеш.

new_hash = Hash.new
hash.each do |name , category|
  if new_hash.key?(category)
    new_file[category] << name 
  else
    new_hash[category] = [name] # <- must be an array    
  end
end
1 голос
/ 14 мая 2019

Как я могу реструктурировать этот код, чтобы '.each' не предоставлял замороженные переменные?

Краткий ответ: вы не можете.

Hash#each не "предоставляет замороженные переменные".

Во-первых, не существует такой вещи, как "замороженная переменная". Переменные не заморожены. Объекты есть. Различие между переменными и объектами является фундаментальным , не только в Ruby, но и в любом языке программирования (и на самом деле в значительной степени везде, также). Если у меня есть наклейка с именем «Симус», то эта наклейка - не вы. Это просто ярлык, который относится к вам.

Во-вторых, Hash#each не предоставляет «переменных». Фактически, он не предоставляет ничего, чего уже нет в хэше. Он просто возвращает объекты, которые уже находятся в хэше.

Обратите внимание, что во избежание путаницы и ошибок строки автоматически замораживаются при использовании в качестве ключей. Таким образом, вы не можете изменять строковые ключи. Вы можете либо убедиться, что они верны с самого начала, либо создать новый хеш с новыми строковыми ключами. (Вы также можете добавить новые ключи к существующему хешу и удалить старые ключи, но это очень сложно для небольшого выигрыша.)

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