为什么我的instance_variable为零? (2行代码)

时间:2011-01-29 22:43:45

标签: ruby instance-variables monkeypatching

我正在尝试创建一个哈希值,用于存储不存在的密钥的自动增量编号。 我知道还有其他不那么脆弱的方法可以做到这一点;我的问题是:为什么我的实例变量如此悲惨地失败?

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 个答案:

答案 0 :(得分: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关联的实例变量。更详细,但你需要什么。