2015-12-23 2 views
2

Пример разъяснит вопрос:Пользовательские Struct не может установить STRUCT элемент

Val = Struct.new(:value) do 
    def inc 
    p value 
    value = value + 1 
    end 
end 

v = Val.new(1) 
v.inc 

Выход будет:

1 
undefined method `+' for nil:NilClass (NoMethodError) 

Почему я получаю эту ошибку, когда value явно не ноль ? Есть ли способ сделать эту работу?

ответ

3

Уточнение ответа Серхио.

В определении inc «s, не существует изначально ни одна переменная value, и то, что называют p value метод value, который возвращает 1.

Затем в строке value = value + 1, в тот момент, когда value = был разобранный, локальная переменная value создается и инициализируется nil. Несмотря на то, что value + 1 оценивается до присвоения его значения во вновь созданный value, сначала выполняется инициализация value. Итак, когда необходимо оценить value + 1, уже существует локальная переменная value, которая имеет приоритет, который вызывается по методу value. И это значение nil.

+0

Мое единственное остающееся замешательство: почему «я». не подразумевается, как это обычно бывает? является ли это правило неприменимым к операторам присваивания вообще? – Jonah

+1

Если вызов метода (с неявным 'self'-приемником) имел приоритет над локальной переменной, тогда не было бы способа вызвать эту переменную. – sawa

+0

ну, это может сработать, если вы запретили имена меток затенения локальными варами, не так ли? но я получаю вашу точку – Jonah

5
Val = Struct.new(:value) do 
    def inc 
    p value # here it still prints 1 

    # but here you REDEFINED what value is. It is now a local variable! 
    # Also its initial value is nil, hence the error you're getting. 
    value = value + 1 

    # should have used this instead, to reference the method 
    self.value = value + 1 
    end 
end 
Смежные вопросы