Hash.default
используется для установки значения по умолчанию , возвратился , когда Вы запрашиваете ключ, который не существует. Запись в наборе не создается для Вас, просто потому что запрошенный это.
кроме того, значение Вы устанавливаете default
на, экземпляр объекта (Массив в Вашем случае), поэтому когда это возвращается, этим можно управлять.
a = {}
a.default = [] # set default to a new empty Array
a[8] << 9 # a[8] doesn't exist, so the Array instance is returned, and 9 appended to it
a.default # => [9]
a[9] # a[9] doesn't exist, so default is returned
Это - очень полезная идиома:
(myhash[key] ||= []) << value
Это может даже быть вложено:
((myhash[key1] ||= {})[key2] ||= []) << value
другой путь состоит в том, чтобы сделать:
myhash = Hash.new {|hash,key| hash[key] = []}
, Но это имеет значительный побочный эффект, что выяснение о ключе создаст его, который представляет has_key? довольно бесполезный, таким образом, я избегаю этого метода.
Я думаю, что это - поведение, которое Вы ищете. Это автоматически инициализирует любые новые ключи в Хеше к массиву:
irb(main):001:0> h = Hash.new{|h, k| h[k] = []}
=> {}
irb(main):002:0> h[1] << "ABC"
=> ["ABC"]
irb(main):003:0> h[3]
=> []
irb(main):004:0> h
=> {1=>["ABC"], 3=>[]}
irb(main):002:0> a.default = []
=> []
irb(main):003:0> a[8] << 9
=> [9] # great!
С этим оператором, Вы изменили значение по умолчанию; Вы не создали новый массив и добавили "9". На данном этапе это идентично тому, если Вы сделали это вместо этого:
irb(main):002:0> a.default = [9]
=> [9]
Следовательно не удивительно, что Вы теперь получаете это:
irb(main):006:0> a[9]
=> [9] # unawesome! shouldn't this be [] ??
, Кроме того, '< <'; добавленный '9' к массиву; это не добавило его к хешу, который объясняет это:
irb(main):004:0> a
=> {} # ?! would have expected {8=>[9]}
Вместо того, чтобы использовать .default, что Вы, вероятно, хотите сделать в своей программе, что-то вроде этого:
# Time to add a new entry to the hash table; this might be
# the first entry for this key..
myhash[key] ||= []
myhash[key] << value
Я не уверен, является ли это тем, что Вы хотите, но можно сделать это, чтобы всегда возвратить пустой массив, когда недостающий ключ хеша запрашивается.
h = Hash.new { [] }
h[:missing]
=> []
#But, you should never modify the empty array because it isn't stored anywhere
#A new, empty array is returned every time
h[:missing] << 'entry'
h[:missing]
=> []
Гленн Макдональд говорит:
«Другой способ - сделать:
myhash = Hash.new {| hash, key | hash [key ] = []}
Но у этого есть существенный побочный эффект: вопрос о ключе создаст его, что делает has_key? Довольно бесполезным, поэтому я избегаю этого метода »
, который на самом деле не кажется правда.
irb(main):004:0> a = Hash.new {|hash,key| hash[key] = []}
=> {}
irb(main):005:0> a.has_key?(:key)
=> false
irb(main):006:0> a[:key]
=> []
irb(main):007:0> a.has_key?(:key)
=> true
Доступ к ключ создаст его, как я и ожидал. Просто спросите has_key? не.