如何处理组合 + =在Ruby中自动生成哈希?
为了实现Ruby哈希的自动生成,可以使用以下类
class AutoHash 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 pa[:c] # => {} # key :c has not been created pa # => {: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 }
你会做什么来处理它? 可以定义[]+=
运算符吗?
相关问题
- 是否可以在Ruby中自动初始化多维哈希数组,就像在PHP中一样?
- 使用Ruby ruby哈希初始化r中的新运算符多次初始化自动生成哈希
- 仍然开放: 如何在Ruby中创建一个深层复制/克隆对象的运算符?
无法在ruby中定义[]+=
方法。 键入时会发生什么
x[y] += z
是
x[y] = x[y] + z
所以在x
上调用[]
和[]=
方法(在x[y]
上调用+
,在这种情况下是AutoHash
)。 我认为处理这个问题的最好方法是在AutoHash
上定义一个+
方法, AutoHash
返回它的参数。 这将使AutoHash.new[:x] += y
几乎适用于任何类型的y
,因为y.class
的“空”版本( ''
表示字符串, 0
表示数字,…)加y
将几乎永远等于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
🙂
我认为你想要的是:
hash = Hash.new { |h, k| h[k] = 0 }
hash['foo'] += 3
# => 3
那将返回3,然后是6等,没有错误,因为新值默认分配为0。
require 'xkeys' # on rubygems.org a = {}.extend XKeys::Hash a[:a, :b] = 1 pa[:c] # => nil (key :c has not been created) pa # => { :a => { :b => 1 } } a.clear 5.times { a[:sum, :else => 0] += 10 } pa # => { :sum => 50 }