1

我希望有人可以阐明我在下面收到的错误。我在父类中定义了一个实例变量,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
4

3 回答 3

4

您需要在子类的初始化程序中调用超级初始化程序。

class AddSubNode < Node
  def initialize op, l, r
    super()
    @op = op
    @l  = l
    @r  = r
  end
...

编辑:忘记括号

于 2013-04-14T22:14:20.953 回答
2

当您initialize在子类中重新定义方法时,您会覆盖原来的方法。因此,实例变量@code永远不会被初始化,并且当您调用@code << 1.

super()从子类中的方法调用initialize(有效地调用它的父类)或利用@code << 1 unless @code.nil?是解决错误的几种方法。

于 2013-04-14T22:18:34.763 回答
2

这里我只是试着给你一些可视化来测试这样的场景。

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]
于 2013-04-15T06:36:47.797 回答