Инициализация переменной экземпляра в Ruby - PullRequest
7 голосов
/ 03 марта 2012

Я думаю, что немного схожу с ума, когда пытаюсь понять переменные экземпляра в 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 ]

11 голосов
/ 03 марта 2012

То, что вы делаете, это определение переменной экземпляра на уровне класса (поскольку классы являются экземплярами класса 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]
2 голосов
/ 03 марта 2012
# 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
0 голосов
/ 03 марта 2012

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

...