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を呼び出すには、proc.callを実行する必要があると思いました。

前もって感謝します

4

1 に答える 1

9

あなたはそれを間違った方法で取っています。&hこの文脈では意味のある単位ではありません。に&付属していh.default_procます。これは、proc h.default_procブロックに変換されたものです。同様のことがスプラット演算子にも当てはまります*&との結合優先順位*は常に最後です。理由は明らかです。それ以外の場合は意味がありません。


あなたが持っているとしましょう:

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 に答える