Ruby中的实例变量初始化

sas*_*uke 7 ruby metaprogramming

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

class Test

  @my = []

  attr_accessor :my

end
t = Test.new
t.my # I want [] but this shows nil
Run Code Online (Sandbox Code Playgroud)

是否有可能实现这一目标而不触及initialize?谢谢.

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

Dom*_*nef 11

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

不,没有办法初始化.

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

def my; @my; end
def my=(value); @my = value; end
Run Code Online (Sandbox Code Playgroud)

它不主动创建/初始化任何实例变量,它只定义了两个方法.你可以通过使用来编写自己的类方法来完成类似的事情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]
Run Code Online (Sandbox Code Playgroud)

  • 不.(还有9个) (2认同)
  • StackOverflow上的注释必须至少为15个字符."不." 时间不长;) (2认同)