Для реализации автоматического вивификация рубина хэш, можно использовать следующий классКак обрабатывать комбинацию [] + = для автоживущего хеша в Ruby?
class AutoHash < Hash
def initialize(*args)
super()
@update, @update_index = args[0][:update], args[0][:update_key] unless
args.empty?
end
def [](k)
if self.has_key?k
super(k)
else
AutoHash.new(:update => self, :update_key => k)
end
end
def []=(k, v)
@update[@update_index] = self if @update and @update_index
super
end
def few(n=0)
Array.new(n) { AutoHash.new }
end
end
Этот класс позволяет сделать следующие вещи
a = AutoHash.new
a[:a][:b] = 1
p a[:c] # => {} # key :c has not been created
p a # => {:a=>{:b=>1}} # note, that it does not have key :c
a,b,c = AutoHash.new.few 3
b[:d] = 1
p [a,b,c] # => [{}, {:d=>1}, {}] # hashes are independent
Существует a bit more advanced definition этого класса proposed by Joshua, который для меня немного сложно понять.
Проблема
Существует одна ситуация, когда я думаю, что новый класс может быть улучшен. Следующий код выдает сообщение об ошибке NoMethodError: undefined method '+' for {}:AutoHash
a = AutoHash.new
5.times { a[:sum] += 10 }
Что бы вы сделали, чтобы справиться с этим? Можно ли определить оператора []+=
?
Похожие вопросы
- Is auto-initialization of multi-dimensional hash array possible in Ruby, as it is in PHP?
- Multiple initialization of auto-vivifying hashes using a new operator in Ruby ruby hash initialization r
- все еще открыт:How to create an operator for deep copy/cloning of objects in Ruby?
Что вы пытаетесь сделать с последний фрагмент кода, и что вы хотите? Если вы хотите, чтобы 'a [: sum]' равнялось 50, вам нужно будет инициализировать его до нуля до строки '5.times', потому что нет возможности для AutoHash знать, что вы хотите сохранить в нем цифры , – Adrian