Инициализация переменной экземпляра в Ruby

Я думаю, что я немного схожу с ума, пытаясь понять переменные экземпляра в Ruby. Моя единственная цель здесь - убедиться, что каждый объект, созданный для данного класса, имеет переменную с заданным значением без пишем initialize метод для этого класса. Что-то вроде:

class Test

  @my = []

  attr_accessor :my

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

возможно ли достичь этого, не касаясь initialize ? Спасибо.

EDIT: чтобы уточнить, я пишу некоторый фрагмент кода, который будет выполнен похожие на attr_accessor в том смысле, что он добавит переменную экземпляра в класс, в котором она выполняется. Если я пишу initialize, Я закончу тем, что ударю того, кто написан пользователем.

3 ответов


то, что вы делаете, - это определение переменной экземпляра на уровне класса (поскольку классы являются экземплярами класса Class, это работает просто отлично).

и нет, нет никакого способа обойти инициализацию.

Edit: у вас есть небольшое заблуждение в вашем редактировании. attr_accessor не добавляет переменную экземпляра в класс. То, что он делает, буквально, это (используя Ваш пример my):

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

он не активно создает / инициализирует какие-либо переменная экземпляра, она просто определяет два метода. И вы можете очень хорошо написать свой собственный метод класса, который делает подобные вещи, используя define_method.

Edit 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]

# 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

Я не думаю, что это так, почему вы так не решаетесь просто написать быстрый метод инициализации?