Инициализация переменной экземпляра в 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