Rails: ноль ошибка, где я уверен, что объект не ноль - PullRequest
1 голос
/ 02 августа 2011

Этот метод увеличивает атрибут ActiveRecord attr_accessible current_step:

def next_step
  logger.debug "Now at step: " + current_step.inspect
  if (current_step == nil)
    current_step = 0
  end
  current_step = current_step + 1
end

При выполнении метода в журнале отображается Now at step: 0, но в строке +1 происходит сбой:

NoMethodError (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.+):
  app/models/assessment.rb:16:in `next_step'

Это чудо? current_step ноль или нет?


РЕДАКТИРОВАТЬ: Спасибо fl00r и whitequark за отличные ответы! Вот то, что код должен был быть:

def next_step
  current_step ||= 0
  self.current_step += 1
  save
end

Ответы [ 2 ]

3 голосов
/ 02 августа 2011

Условные выражения и циклы не имеют своей области видимости в Ruby; и здесь у вас есть переменная и метод self, которые имеют одно и то же имя. В состоянии if используется метод current_step, но в его теле определяется локальная переменная, и все будущие ссылки на current_step будут ссылаться на локальную переменную. Подводный камень, с которым вы столкнулись, даже если тело if не выполнено, локальная переменная все еще определена, и ей присвоено значение по умолчанию nil.

Я поясню это, добавив _M к идентификатору при обращении к методу и _L для локальной переменной.

def next_step
  logger.debug "Now at step: " + current_step_M.inspect
  if (current_step_M == nil)
    current_step_L = 0
  ### this part is implicit:
  # else
  #   current_step_L = nil
  end
  current_step_L = current_step_L + 1
end

Полагаю, вы на самом деле пытались выполнить self.current_step = 0, что вызвало бы сеттер.

1 голос
/ 02 августа 2011
def next_step
  current_step ||= 0
  logger.debug "Now at step: " + current_step.inspect
  current_step += 1
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...