示例代码和输出可以在这里找到:
module A
def self.included(base)
base.include InMethods
end
module InMethods
def mem
@mem ||= []
end
def add(n)
mem += n
end
end
end
class Help
include A
end
h = Help.new
h.add(1)
# in `add': undefined method `+' for nil:NilClass (NoMethodError)
基本上,我包含一个包含子模块的模块,但真正的问题在于方法和实例变量。这对我来说是一种常见的模式,但由于我试图从我所包含的模块中做到这一点,我遇到了麻烦。
答案 0 :(得分:2)
这实际上与模块/包含/继承/无关。你在常规课程中得到同样的错误。
class Help
def mem
@mem ||= 0
end
def add(n)
mem += n
end
end
Help.new.add(1)
# test.rb:16:in `add': undefined method `+' for nil:NilClass (NoMethodError)
当你使用语法糖mem +=
时,Ruby实际上将其扩展为mem = mem +
。第一个问题是这是从左到右解释的,因此mem =
定义了一个掩盖方法的局部变量mem
。那么第二个mem
引用一个已定义但未设置的局部变量,你得到nil
。
第二个问题是你没有定义一个setter mem=
方法,所以它根本不能改变@mem
!
要解决这两个问题,你可以做到
attr_writer :mem
def add(n)
self.mem += n
end