如何在Ruby中初始化类实例变量?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

我正在开发一个小型Rails应用程序,并且遇到了ruby的OOP模型的问题。我有以下简化的结构。

class Foo
  protected
    @bar = []
    def self.add_bar(val)
      @bar += val
    end
    def self.get_bar
      @bar
    end
end

class Baz < Foo
  add_bar ["a", "b", "c"]
end

我现在的问题是,当我call给Add_bar在Baz的类定义中,@bar显然没有初始化,并且我得到一个错误,即+运算符不可用于nil

我期望的结果:

Foo.add_bar ["a", "b"]
Baz.add_bar ["1", "2"]
Foo.get_bar # => ["a", "b"]
Baz.get_bar # => ["a", "b", "1", "2"]

提问于
用户回答回答于

实例变量不会被子类继承

这是一个例子

class Foo
  @bar = "I'm defined on the class object Foo. self is #{self}"

 def self.get_bar
    puts "In the class method. self is #{self}"    
    @bar
  end

  def get_bar
    puts "In the instance method. self is #{self} (can't see @bar!)"
    @bar
  end
end

>> Foo.get_bar
In the class method. self is Foo
=> "I'm defined on the class object Foo. self is Foo"

>> Foo.new.get_bar
In the instance method. self is #<Foo:0x1056eaea0> (can't see @bar!)
=> nil

无可否认,这有点令人困惑,也是Ruby新手的常见绊脚石,所以不要感觉不好。

看看Rails的class_attribute方法。它允许你试图做的事情(在父类上定义一个可以在其子类中继承的属性)。

用户回答回答于

因为@bar被定义为类实例变量,所以它仅限于foo类。

class Foo
    @bar = []
end

class Baz < Foo
end

Foo.instance_variables #=> [:@bar]
Baz.instance_variables #=> []

无论如何,对于这个简单的例子,可以这样做:

class Foo
  protected
    def self.add_bar(val)
      @bar ||=[]
      @bar += val
    end
    def self.get_bar
      @bar
    end
end

class Baz < Foo
  add_bar ["a", "b", "c"]
end

扫码关注云+社区