2012-03-03 7 views
6

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

class Test 

    @my = [] 

    attr_accessor :my 

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

Можно ли достичь этого, не касаясь initialize? Благодарю.

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

ответ

11

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

И нет, нет инициализации.

Редактировать: У вас есть небольшое заблуждение в вашем редактировании. 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] 
+0

См. Редактирование. – sasuke

+0

Мой плохой, я сказал «похоже на». В принципе, этот новый метод, добавленный в любой класс, например 'attr_accessor', добавит новую переменную экземпляра ко всем объектам, созданным для этого класса. – sasuke

+1

Ах, как я думал, я не могу полагаться на default 'attr_reader' для таких атрибутов. Только один последний вопрос: нет способа инициализировать переменные экземпляра, например, как это делается для Java и т. Д. В Ruby? – sasuke

0

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

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 
+1

+1, особенно. для переменной уровня класса с аксессуарами. Переменные экземпляра caveat re без 'initialize' состоят в том, что если вы попытаетесь установить' t.my = nil', 't.my' вернется к' [] 'из-за' || = ', что является неожиданным и может не быть желательным; лучше не избегать «инициализации». – mklement0

Смежные вопросы