Вот хорошая статья на эту тему - Переменные класса и экземпляра в Ruby .
По сути, вы можете сделать следующее:
class A
class << self
attr_accessor :class_var
end
def set_class_var(value)
self.class.class_var = value
end
def get_class_var
self.class.class_var
end
end
class B < A; end
A.class_var = 'a'
B.class_var = 'b'
puts A.class_var # => a
puts B.class_var # => b
A.new.set_class_var 'aa'
B.new.set_class_var 'bb'
puts A.new.get_class_var # => aa
puts B.new.get_class_var # => bb
Чтобы понять это, вы должны подумать о A
как об экземпляре класса Class
(и это так в Ruby). Но каждый объект в Ruby имеет свой собственный одноэлементный класс, который хранит специфичные для объекта вещи, такие как методы, определенные для самого объекта:
a = A.new
def a.foo
puts 'foo'
end
В этом случае foo
- это метод, определенный только для объекта a
, а не для каждого экземпляра класса A
. И еще один способ определить метод в одноэлементном классе объекта:
class << a # open a's singleton class
def bar # define method that will be available only on 'a' object
puts 'bar'
end
end
В первом фрагменте кода мы используем этот подход для определения средства доступа к атрибуту class_var
в контексте одноэлементного класса нашего A
класса (это немного сложно, поэтому вам нужно подумать об этом). В результате у самого класса есть переменная class_var
, а также класс-потомок B
. Разница в том, что у каждого из них есть собственная переменная class_var
, которая не мешает работе.