以下代码取自RubyTapas截屏视频,但对于我的经验人员来说,没有充分解释。设置像这样的哈希
config = Hash.new do |h,k|
h[k] = Hash.new(&h.default_proc)
end
允许用户以下列方式设置和访问值
config[:production][:database][:adapter] = 'mysql'
puts config[:production][:database][:adapter] # => "mysql"
当我这样做时
puts config.inspect
它显示了嵌套哈希。
{:production=>{:database=>{:adapter=>"mysql"}}}
但是,如果我修改代码(只是玩它)来删除& h.default_proc
config = Hash.new do |h,k|
h[k] = Hash.new() #&h.default_proc removed from parameter
end
我收到此错误
undefined method `[]=' for nil:NilClass (NoMethodError)
我不知道Hash.new(& h.default_proc)发生了什么,例如,当我这样做时
config[:production][:database][:adapter] = 'mysql'
puts config[:production][:database][:adapter] # => "mysql"
你可以分解一下,详细解释块&hdefault_proc
在这种情况下是如何工作的。请解释是否可以在proc被调用时。为什么必须使这个工作成功
config[:production][:database][:adapter] = 'mysql'
如何调用proc?我以为你必须做proc.call来实际调用proc。
提前致谢
答案 0 :(得分:6)
你采取了错误的方式。在这种情况下,&h
不是一个有意义的单位。它&
附加h.default_proc
。这是 proc h.default_proc
变为块。类似的东西适用于splat运算符*
。 &
和*
的关联优先级始终是最后一个。原因很清楚:否则没有意义。
假设你有:
config = Hash.new() # or `{}`
然后,只要您使用不存在的密钥访问config
,它就会返回nil
,所以
config[:production][:database]
将返回错误,因为[]
上未定义方法config[:production]
,等于nil
。当你这样做时:
config = Hash.new do |h,k|
h[k] = Hash.new()
end
然后,将确保当您使用不存在的密钥访问config
时,它会创建一个新的哈希值作为值。所以
config[:production][:database]
现在可以了,因为方法[]
是在config[:production]
上定义的,它等于新创建的哈希{}
。但是,仍然,
config[:production][:database][:adapter]
将返回错误,因为[]
上未定义方法config[:production][:database]
,等于nil
。如果您改为:
config = Hash.new do |h,k|
h[k] = Hash.new(&h.default_proc)
end
然后,这意味着,当您使用不存在的密钥访问config
时,如:
config[:production]
此次创建的哈希将default_proc
设置为与config
相同的哈希,这意味着
config[:procuction][:database]
不是将nil
返回到不存在的键调用的哈希,而是将哈希返回到不存在的键调用的哈希。所以这次,
config[:production][:database][:adapter]
不会返回错误。类似的事情发生在哈希中的任意深度。