我希望有人可以对我在下面收到的错误有所了解。我在父类Node
中定义了一个实例变量,并希望在子类AddSubNode
中访问和修改它,每当我尝试访问@code
时,我都会收到此错误:
'code': undefined method `<<' for nil:NilClass (NoMethodError)
我必须误解Ruby的继承模型,但我认为我可以做到这一点。
class Node
attr_accessor :code
def initialize
@code = []
end
end
class AddSubNode < Node
def initialize op, l, r
@op = op
@l = l
@r = r
end
def code
@code << 1 # error: `code': undefined method `<<' for nil:NilClass (NoMethodError)
@code
end
def to_s
"#{@l} #{@op} #{@right}"
end
end
答案 0 :(得分:4)
您需要在子类的初始值设定项中调用超级初始值设定项。
class AddSubNode < Node
def initialize op, l, r
super()
@op = op
@l = l
@r = r
end
...
编辑:忘记括号
答案 1 :(得分:2)
重新定义子类中的initialize
方法时,将覆盖原始方法。因此,实例变量@code
永远不会被初始化,并且您在调用@code << 1
时代码会引发错误。
从子类中的super()
方法调用initialize
(有效地调用它的父级)或使用@code << 1 unless @code.nil?
是解决错误的几种方法。
答案 2 :(得分:1)
在这里,我试图给你一些可视化来测试这些场景。
class Node
attr_accessor :code
def initialize
@code = []
end
end
class AddSubNode < Node
def initialize op, l, r
@op = op
@l = l
@r = r
end
def code
@code << 1 # error: `code': undefined method `<<' for nil:NilClass (NoMethodError)
@code
end
end
ob = AddSubNode.new(1,2,3)
p ob.instance_variables #=> [:@op, :@l, :@r]
p ob.instance_variable_defined?(:@code) #=> false
p ob.instance_variable_set :@code,[12] #=> [12]
p ob.instance_variable_defined?(:@code) #=> true
p ob.instance_variable_get :@code #=> [12]
p ob.instance_variables #=> [:@op, :@l, :@r, :@code]
p ob.code #=> [12, 1]