29

Если у меня есть класс с attr_accessor, он по умолчанию создает переменную экземпляра вместе с соответствующими геттерами и сеттерами. Но вместо того, чтобы создавать переменную экземпляра, есть ли способ заставить его создать переменную класса или переменную экземпляра класса?Как attr_accessor Ruby может создавать переменные класса или переменные экземпляра класса вместо переменных экземпляра?

+0

Пройдите свой путь через «[Ясно видеть метаклассы] (http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html)"; это очень полезно при попытке понять, как работают классы и объекты Ruby. –

ответ

46

Как это:

class TYourClass 
    class << self 
    attr_accessor :class_instance_variable 
    end 
end 

Вы можете смотреть на это как открытие метакласса класса (из которых сам класс является экземпляром) и добавление к нему атрибут.

attr_accessor - метод класса Class, он добавляет к классу два метода: тот, который считывает переменную экземпляра, и другую, которая ее устанавливает. Вот возможная реализация:

class Class 
    def my_attr_accessor(name) 
    define_method name do 
     instance_variable_get "@#{name}" 
    end 
    define_method "#{name}=" do |new_val| 
     instance_variable_set "@#{name}", new_val 
    end 
    end 
end 

Полностью тестировался атрибут класса сбруя:

class Class 
    def class_attr_accessor(name) 
    define_method name do 
     class_variable_get "@@#{name}" 
    end 
    define_method "#{name}=" do |new_val| 
     class_variable_set "@@#{name}", new_val 
    end 
    end 
end 
+0

Спасибо. Мне нравится ваш способ сказать, что он открывает метакласс класса, а также добавляет добавление. Но почему он создает переменную экземпляра класса вместо переменной класса? И возможно ли получить его для создания переменной класса, или этот синтаксис будет работать только для переменных экземпляра класса? –

+0

Я другой, см. Ответ снова –

+0

Это будет работать только для переменных экземпляра класса, b/c attr_ * определяет методы для переменных экземпляра (некоторого объекта). – rampion

20

В Rails (или где вы require 'active_support'), вы можете использовать cattr_accessor :name, чтобы получить переменные аксессор истинного класса.

Переменные экземпляра класса, которые другие указали, обычно более полезны. У APIdock cattr_accessor page есть полезная дискуссия, поясняющая, когда вы захотите, а не другой, плюс источник для функций cattr_accessor, cattr_reader и cattr_writer.

+0

намного проще - не знал, что рельсы предложили это. Благодаря! –

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