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 回答