2011-01-29 11 views
1

存在しないキーの自動インクリメント番号を格納するハッシュを作成しようとしています。 私はこれを行うための他の脆弱ではない方法があることを認識しています。私の質問です:なぜ私のインスタンス変数は非常に惨めに失敗しますか?なぜ私のinstance_variableはnilですか? (2行のコード)

h = Hash.new{|h,k| h[k] = (@max_value += 1)} 
h.instance_variable_set(:@max_value, 0) # zero ! Not nil! Argh... 

puts h[:a] # expecting 1; getting NoMethodError undefined method '+' for nil:NilClass 
puts h[:b] # expecting 2 
puts h[:a] # expecting 1 

答えて

1

あなたが行っているとは思わないようにしています。

Hash.newを呼び出すと、今現在のスコープに存在する@max_value が参照されています。現在のスコープはトップレベルですが、そこに定義されていないため、ゼロになります。

この場合、@max_valueと呼ばれるインスタンス変数を設定しますが、それは同じではありません。

あなたはおそらく...まあ、実際には、私はこのメカニズムが何かの良い解決策である状況を想像することはできませんが、それはあなたがそれを実行できるように頼んだものです。

h = Hash.new{|h,k| h[k] = (h.instance_variable_set(:@max_value,  
           h.instance_variable_get(:@max_value) + 1))} 

h.instance_variable_set :@max_value, 0 

puts h[1] #=> 1 
puts h[10] #=> 2 

私は明示的にすべての場合に `hと関連付けられたインスタンス変数を取得/設定しています。もっと冗長だが、必要なもの。

関連する問題