在研究this Railscast时,我从Rack中看到了以下一些源代码:
def self.middleware
@middleware ||= begin
m = Hash.new {|h,k| h[k] = []}
m["deployment"].concat [
[Rack::ContentLength],
[Rack::Chunked],
logging_middleware
]
m["development"].concat m["deployment"] + [[Rack::ShowExceptions], [Rack::Lint]]
m
end
end
我的问题是关于第三行。将块{|h,k| h[k] = []}
传递给Hash.new
的成就是什么?我在IRB中尝试了它,它似乎与常规Hash.new
:
2.0.0p247 :003 > m1 = Hash.new
=> {}
2.0.0p247 :004 > m2 = Hash.new{|h,k| h[k] = []}
=> {}
2.0.0p247 :005 > m1 == m2
=> true
...但是我猜猜那些编写Rack的人比我更了解Ruby。包含该块的原因是什么?
答案 0 :(得分:11)
它允许您将默认值定义为数组
h = Hash.new { |h, k| h[k] = [] }
h[:a] # => {:a=>[]}
h[:b] << 123 # => {:a=>[], :b=>[123]}
此处有更多示例:Hash.new
答案 1 :(得分:2)
这将创建默认对象(在这种情况下为[])作为每个键的值。它隐式调用h1 [:a] = [],导致哈希中添加了密钥。
h1 = Hash.new {|h,k| h[k] = []}
h1[:a] # = []
h1[:a].push(1) # = [1]
h1[:b] # = []
h1 #= {:a=>[1], :b=>[]}
这将返回一个默认对象作为所有键的值。
h1 = Hash.new([])
h1[:a] # = []
h1[:a].push(1) # = [1]
h1[:b] # = [1]
h1 #= {}
这将返回默认对象作为所有键的值。但是不会向哈希添加密钥。
h1 = Hash.new{[]}
h1[:a] # = []
h1[:a].push(1) # = [1]
h1[:b] # = []
h1 #= {}