问题描述
为了实现Ruby哈希的自动生成,可以使用以下类:
class AutoHash<哈希
def初始化(* args)
super()
@update,@update_index = args [0] [:update],args [0] [:update_key]除非
args.empty?
结束
def [](k)
如果self.has_key?k
super(k)
else
AutoHash.new :update => self,:update_key => k)
end
end
def [] =(k,v)
@update [@update_index ] = self如果@update和@update_index
super
end
def few(n = 0)
Array.new(n){AutoHash.new}
end
end
该类允许执行以下操作
a = AutoHash.new
a [:a] [:b] = 1
pa [:c]#=> ; {}#键:c尚未创建
p a#=> {:a => {:b => 1}}#注意,它没有键:c
a,b,c = AutoHash.new.few 3
b [ :d] = 1
p [a,b,c]#=> [{},{:d => 1},{}]#散列是独立的
这个类 仍然打开: 如何创建深层复制操作符/在Ruby中克隆对象? 在Ruby中使用 是 所以 添加该方法将使这两个工作成为可能: 顺便说一下,这里是一个清洁工您的代码版本: :) In order to implement auto-vivification of Ruby hash, one can employ the following class This class allows to do the following things There is a bit more advanced definition of this class proposed by Joshua, which is a bit hard for me to understand. Problem There is one situation, where I think the new class can be improved. The following code fails with the error message What would you do to handle it? Can one define Related questions There is no way to define a is so both the Adding that method will make both of these work: And by the way, here is a cleaner version of your code: :) 这篇关于如何处理组合[] + =用于在Ruby中自动生成散列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
[] + =
方法。当你输入
x [y] + = z
x [y] = x [y] + z
[]
和 x (并且 +
>)上调用code> [] = 调用 x [y]
,在这种情况下,它是 AutoHash
)。我认为处理这个问题的最好方法是在 AutoHash
上定义一个 +
方法,它会返回这是争论。这将使 AutoHash.new [:x] + = y
几乎适用于任何类型的 y
,因为 y.class
('
为字符串, 0
为数字,...)加 y
几乎总是等于 y
。
class AutoHash
def +(x); X; end
end
#数字:
a = AutoHash.new
5.times {a [:sum] + = 10}
a [:sum]#=> 50
#字符串:
a = AutoHash.new
5.times {a [:sum] + ='a string'}
a [:sum]#= > 一个字符串一个字符串一个字符串一个字符串一个字符串
class AutoHash<哈希
def初始化(args = {})
super
@update,@update_index = args [:update],args [:update_key]
结束
def [](k)
如果has_key? k
super(k)
else
AutoHash.new:update => self,:update_key => k
end
end
def [] =(k,v)
@update [@update_index] = self如果@update和@update_index
超级
结束
def +(x); X; end
$ b $ def self.few(n)
Array.new(n){AutoHash.new}
end
end
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
NoMethodError: undefined method '+' for {}:AutoHash
a = AutoHash.new
5.times { a[:sum] += 10 }
[]+=
operator?[]+=
method in ruby. What happens when you typex[y] += z
x[y] = x[y] + z
[]
and []=
methods are called on x
(and +
is called on x[y]
, which in this case is an AutoHash
). I think that the best way to handle this problem would be to define a +
method on AutoHash
, which will just return it's argument. This will make AutoHash.new[:x] += y
work for just about any type of y
, because the "empty" version of y.class
(''
for strings, 0
for numbers, ...) plus y
will almost always equal y
.class AutoHash
def +(x); x; end
end
# Numbers:
a = AutoHash.new
5.times { a[:sum] += 10 }
a[:sum] #=> 50
# Strings:
a = AutoHash.new
5.times { a[:sum] += 'a string ' }
a[:sum] #=> "a string a string a string a string a string "
class AutoHash < Hash
def initialize(args={})
super
@update, @update_index = args[:update], args[:update_key]
end
def [](k)
if 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 +(x); x; end
def self.few(n)
Array.new(n) { AutoHash.new }
end
end