2015-10-26 3 views
2

Я хотел использовать значения хэш-значения по умолчанию Ruby, чтобы я мог легче хешировать гнезда без необходимости их инициализации вручную. Я подумал, что было бы неплохо иметь возможность выровнять уровень для каждого ключа безопасно, не предварительно задав ключ как хэш. Тем не менее, я нахожу, что когда я это делаю, данные где-то хранятся, но не видны путем доступа к хэшу верхнего уровня. Куда он идет, и как это работает?Значение по умолчанию для хэша Ruby: куда идут вложенные значения?

top = Hash.new({})    #=> {} 
top[:first][:thing] = "hello" #=> "hello" 
top[:second] = {thing: "world"} #=> {:thing => "world"} 
top        #=> {:second => {:thing => "world"}} 
top[:first]      #=> {:thing => "hello"} 
+0

Пожалуйста, удалите подсказки. Они затрудняют чтение и предотвращают простое копирование и вставку читателей. –

ответ

2

Вы можете получить доступ значение по умолчанию с помощью различных методов #default http://ruby-doc.org/core-2.2.3/Hash.html#method-i-default

top.default 
=> {:thing=>"hello"} 
+0

Ничего себе, совершенно неожиданно, что это будет обновлять значение по умолчанию, а не устанавливать значение в предоставленном ключе. Но уверен, понял, спасибо ~ – tekunokurato

+1

Может быть только одно значение по умолчанию. Если вы по умолчанию «1» или {}, этот точный объект будет использоваться по умолчанию. Bassel в своем ответе показывает, как передать в блоке значение по умолчанию и вернуть этот новый хэш. В его случае блок кода является «одним истинным значением по умолчанию». –

2

Вы также можете сказать, что это, как вы хотите, чтобы действовать, например:

irb(main):058:0> top = Hash.new {|h,k| h[k] = {}; h[k]} 
=> {} 
irb(main):059:0> top[:first][:thing] = "hello" 
=> "hello" 
irb(main):060:0> top[:second] = {thing: "world"} 
=> {:thing=>"world"} 
irb(main):061:0> top 
=> {:first=>{:thing=>"hello"}, :second=>{:thing=>"world"}} 
3

Вы хотите знать, где находится ваш вставленный хэш? Может быть, вы слышали о Schroedingers кошки:

h = Hash.new({}) 
h[:box][:cat] = "Miau" 
=> "Miau" 
h 
=> {} 

Кошка, кажется мертвым ....

h[:schroedingers][:cat] 
=> "Miau" 

кошка, кажется, все еще жив, но в другой реальности ....

Хорошо, если ничего не помогает, «Прочитайте точное руководство». Для Hash.new, мы читаем:

Если OBJ указано, это одного объект будет использоваться для всех значения по умолчанию.

Итак, когда вы пишете h [: box], объект возвращается, и этот объект является другим хэшем, и он случается с пустым.

В этот пустой хэш вы пишете значение ключа.

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

Смежные вопросы