Вам не нужно доступ к исходному хэш-определению - вы можете переопределить метод [] на лету, после того как вы получите его с помощью h.instance_eval, например
h = {1 => 'one'}
h.instance_eval %q{
alias :brackets :[]
def [] key
if self.has_key? key
return self.brackets(key)
else
h = Hash.new
h.default = {}
return h
end
end
}
Но это не собирается, чтобы помочь вам с кодом у вас есть, потому что вы полагаетесь на ненайденном значении возвращать ложное значение (например, ноль), и если вы делаете какие-либо из «нормального» авто -вивификация, связанная с выше, вы получите пустой хеш для необоснованных значений, который оценивается как «истинный».
Вы можете сделать что-то вроде этого - он проверяет только определенные значения и возвращает их. Вы не можете установить их таким образом, потому что у нас нет возможности узнать, находится ли вызов в LHS задания.
module AVHash
def deep(*args)
first = args.shift
if args.size == 0
return self[first]
else
if self.has_key? first and self[first].is_a? Hash
self[first].send(:extend, AVHash)
return self[first].deep(*args)
else
return nil
end
end
end
end
h = {1=>2, 3=>{4=>5, 6=>{7=>8}}}
h.send(:extend, AVHash)
h.deep(0) #=> nil
h.deep(1) #=> 2
h.deep(3) #=> {4=>5, 6=>{7=>8}}
h.deep(3,4) #=> 5
h.deep(3,10) #=> nil
h.deep(3,6,7) #=> 8
Опять же, вы можете проверять только значения - не назначать их. Так что это не настоящая автожизнь, как мы все знаем, и любить ее в Perl.
В заводной вы должны использовать `` оператор?. На самом деле меня интересует эквивалентный оператор. Вы можете расширить класс хэша и добавить оператора. – Pasta 2010-12-06 22:54:34
@Pasta [Io] (http://iolanguage.com) имеет аналогичный оператор, но Ruby этого не делает. – Phrogz 2010-12-06 23:19:43
@JesseSielaff Первоначально это задано в 2010 году. У него 13 ответов (у другого есть 5), больше голосов, больше избранных и немного отличается. Не следует ли дублировать вопрос по другому вопросу? – 2016-01-06 02:42:58