Почему мой instance_variable ноль? (2 строки кода) - PullRequest
1 голос
/ 30 января 2011

Я пытаюсь создать хеш, в котором хранится число автоинкремента для несуществующего ключа.Я знаю, что есть другие, менее хрупкие, способы сделать это;мой вопрос: почему моя переменная экземпляра так ужасно терпит неудачу?

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 Ответ

1 голос
/ 30 января 2011

Вы не делаете то, что, как вы думаете, вы делаете.

Когда вы вызываете 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, во всех случаях.Более многословно, но то, что вам нужно.

...