子类中的实例变量访问

时间:2013-04-14 22:11:43

标签: ruby inheritance

我希望有人可以对我在下面收到的错误有所了解。我在父类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

3 个答案:

答案 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]
相关问题