0

ハッシュ h1 の存在しないキーで遊んでいましたが、いくつかのエラーとその解決策を見て驚きました。再帰呼び出しがエラーを処理するために内部でどのように仕事をしているのか知りたかったのです。

パートⅠ

ここで h1[2][3] を試すとエラーが発生しました。次のパートで解決しました。

irb(main):002:0> h1=Hash.new()
=> {}
irb(main):003:0> h1[2]
=> nil
irb(main):004:0> h1[2][3]
NoMethodError: undefined method `[]' for nil:NilClass
        from (irb):4
        from C:/Ruby193/bin/irb:12:in `<main>'

パートⅡ

以下のハッシュ定義が前のエラーをどのように処理するか。Part-I で可能になったボットの内部アルゴリズム。以下のsysntxが解決したことは知っていますが、内部画面でどのように機能したかを確認したいと思います。

irb(main):005:0> h1 = Hash.new do |h,k|
irb(main):006:1*   h[k] = Hash.new()
irb(main):007:1> end
=> {}
irb(main):008:0> h1[2]
=> {}
irb(main):009:0> h1[2][3]
=> nil

再帰呼び出しを修正できますか? h1[1][2][3] と h1[1][2][3][4] など。

h1[2] で Key を呼び出していたとき-ここで、それ2が探していたキーであることを知っています.今 h1[1][2] - その場合、[1][2] でキーを探している呼び出し-私は正しい?私が正しくない場合、実際のものがバックエンドからどのように機能しているか - それを知りたがっています。

ここで理解するのを手伝ってくれる人はいますか?

ありがとう、

4

2 に答える 2

3
h = Hash.new{|h, k| h[k] = Hash.new(&h.default_proc)}
#demo:
p h[:a][:b][:c]=1 # =>{:a=>{:b=>{:c=>1}}}
于 2013-01-13T11:50:14.947 に答える
2

あなたの質問を正しく理解できれば、再帰的な Proc でやりたいことができると思います。

p = Proc.new { Hash.new { |hash, key| hash[key] = p.call } }
h = Hash.new { |hash, key| hash[key] = p.call }

それから:

h[0][0][0] -> {}

説明:

pはRuby Procです。Proc は Ruby ブロックに似ていますが、完全なオブジェクトであるため、変数に格納できます。

Procs は再帰的にすることができます - それらは自分自身を呼び出すことができます。この例ではそれを利用して、呼び出すハッシュ ツリーの下位レベルが何レベルであっても、新しいデフォルトの Hash 値を作成します。メソッドはProc#callProc を呼び出します。Proc の本体は、そのスコープ外で定義された変数にアクセスできることに注意してください (これはクロージャです)。

steenslags ソリューションは多かれ少なかれ同じことを行っていHash#default_procますが、 Proc 変数を定義する必要を避けるためにプロパティを利用するよりエレガントなワンライナーです。

于 2013-01-13T11:39:41.130 に答える