default_proc如何工作

时间:2012-12-05 23:26:45

标签: ruby

以下代码取自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。

提前致谢

1 个答案:

答案 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]

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