Ruby中的实例变量初始化

时间:2012-03-03 19:22:29

标签: ruby metaprogramming

我想在尝试理解Ruby中的实例变量时我会有点疯狂。我唯一的目标是确保为给定类创建的每个对象都有一个具有预定值的变量,而不用为该类编写initialize方法。类似的东西:

class Test

  @my = []

  attr_accessor :my

end
t = Test.new
t.my # I want [] but this shows nil

是否可以在不触及initialize的情况下实现此目的?感谢。

编辑:为了澄清,我正在编写一些代码,这些代码将执行类似于attr_accessor的意义,因为它会将一个实例变量添加到其中的类中它被执行了。如果我自己写initialize,我最终会破坏用户写的那个。

3 个答案:

答案 0 :(得分:11)

您正在做的是在类级别定义一个实例变量(因为类是Class类的实例,所以这很好用)。

不,没有办法初始化。

修改:您在编辑中有一点误解。 attr_accessor不会向类中添加实例变量。从字面上看,它的作用是什么(使用my的例子):

def my; @my; end
def my=(value); @my = value; end

它不主动创建/初始化任何实例变量,它只定义了两个方法。你可以使用define_method编写自己的类方法来完成类似的事情。

编辑2:

进一步说明如何编写这样的方法:

class Module
  def array_attr_accessor(name)
    define_method(name) do
      if instance_variable_defined?("@#{name}")
        instance_variable_get("@#{name}")
      else
        instance_variable_set("@#{name}", [])
      end
    end

    define_method("#{name}=") do |val|
      instance_variable_set("@#{name}", val)
    end
  end
end


class Test
  array_attr_accessor :my
end

t = Test.new
t.my # => []
t.my = [1,2,3]
t.my # => [1, 2, 3]

答案 1 :(得分:2)

# as instance variable without initialize
class Test1
  def my; @my ||= [] end

  attr_writer :my
end

t = Test1.new
t.my


# as class instance variable
class Test2
  @my = []

  class << self; attr_accessor :my end
end

Test2.my

答案 2 :(得分:0)

我不认为是,你为什么这么犹豫要写一个快速的初始化方法?