这个方法增加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
条件和循环在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
,这将调用setter
def next_step
current_step ||= 0
logger.debug "Now at step: " + current_step.inspect
current_step += 1
end