1

存在しないキーの自動インクリメント番号を格納するハッシュを作成しようとしています。これを行うには、他にも脆弱性の低い方法があることを私は知っています。私の質問は:なぜ私のインスタンス変数はそれほど惨めに失敗するのですか?

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
4

1 に答える 1

1

あなたは自分がしていると思うことをしていません。

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

次に、たまたま@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に関連付けられたインスタンス変数を明示的に取得/設定していることに注意してください。より冗長ですが、必要なもの。

于 2011-01-30T01:19:33.180 に答える