And*_*rei 1 ruby hash autovivification operator-keyword
为了实现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
Run Code Online (Sandbox Code Playgroud)
该类允许执行以下操作
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
Run Code Online (Sandbox Code Playgroud)
还有更多的先进定义这个类的由约书亚提出的,这是一个有点硬,我听不懂.
问题
有一种情况,我认为新课程可以改进.以下代码失败并显示错误消息NoMethodError: undefined method '+' for {}:AutoHash
a = AutoHash.new
5.times { a[:sum] += 10 }
Run Code Online (Sandbox Code Playgroud)
你会做什么来处理它?可以定义[]+=
运营商吗?
相关问题
无法[]+=
在ruby中定义方法.键入时会发生什么
x[y] += z
Run Code Online (Sandbox Code Playgroud)
是
x[y] = x[y] + z
Run Code Online (Sandbox Code Playgroud)
所以无论是[]
和[]=
方法被称为上x
(和+
被称为上x[y]
,在这种情况下是一个AutoHash
).我认为处理这个问题的最好方法是定义一个+
方法AutoHash
,它将返回它的参数.这将AutoHash.new[:x] += y
适用于几乎任何类型的y
,因为y.class
(''
对于字符串,0
数字,...)加上的"空"版本y
几乎总是相等y
.
class AutoHash
def +(x); x; end
end
Run Code Online (Sandbox Code Playgroud)
添加该方法将使这两个工作:
# 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 "
Run Code Online (Sandbox Code Playgroud)
顺便说一句,这是一个更简洁的代码版本:
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
Run Code Online (Sandbox Code Playgroud)
:)