5

以下代码取自 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 时进行说明。为什么需要 proc 才能完成这项工作

    config[:production][:database][:adapter] = 'mysql'

proc是如何被调用的?我认为您必须执行 proc.call 才能真正调用 proc。

提前致谢

4

1 回答 1

9

你采取错误的方式。&h在这种情况下,它不是一个有意义的单位。它&附在h.default_proc. 那是一个proc h.default_proc变成了一个block。类似的事情也适用于 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]

不会返回错误。类似的事情发生在散列中的任意深度。

于 2012-12-05T23:31:18.527 回答