2011-01-29 55 views
1

我想创建一个存储一个不存在的密钥的自动增量编号的散列。 我知道还有其他的,不太脆弱的方法来做到这一点;我的问题是:为什么我的实例变量失败如此悲惨?为什么我的instance_variable为零? (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关联的实例变量。更详细,但你需要什么。