此方法增加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
答案 0 :(得分:3)
条件和循环在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。
答案 1 :(得分:1)
def next_step
current_step ||= 0
logger.debug "Now at step: " + current_step.inspect
current_step += 1
end