Переменные экземпляра класса, как правило, более полезны и менее удивительны, чем переменные класса, поэтому вы, вероятно, должны их использовать.
А теперь я расскажу некоторые вещи в мучительной детали, которую вы ожидаете отРубиновый ответ для StackOverflow:
Чтобы объявить или обратиться к переменной экземпляра класса, вам нужно быть в области действия класса и использовать одиночный @ знак .Это помещает переменную в экземпляр класса singleton для этого класса.
К сожалению, когда вы находитесь в области видимости класса и используете ключевое слово def
, ваши методы помещаются в список методы экземпляра для этого класса и выполняются в область действия экземпляра , поэтому их переменные @ -sign будут в экземпляре, в котором они находятся.
Что мы хотимвместо этого - определять методы в классе, а не в его экземплярах.На самом деле это означает, что эти методы находятся в списке методов экземпляра для одноэлементного класса объекта класса .(Фу!)
Итак, подведем итог: существует не менее четырех идиом для переключения и определения методов в классе синглтона объекта класса Foo
:
class Foo
@a, @b, @c, @d = 1, 2, 3, 4
# 1. pass the target to def
def Foo.a
@a
end
# 2. pass the target to def, relying on the fact that self
# happens to be the class object right now
def self.b
@b
end
# switch from class scope to singleton class scope
class << self
# 3. define a plain accessor in singleton class scope
def c
@c
end
# 4. use a macro to define an accessor
attr_reader :d
end
end
p [Foo.a, Foo.b, Foo.c, Foo.d]
#=> [1, 2, 3, 4]
(Вероятно, есть еще полдюжины способов сделать это, если вы включите class_eval
и define_method
и т.п., но это должно вас удовлетворить. :-))
Последнее замечание: классПеременные экземпляра доступны только через класс, в котором они определены.Если вы попытаетесь вызвать какой-либо из этих методов из (или через) подкласса, методы будут выполнены, но все переменные @ будут иметь значение nil, поскольку self
будет объектом класса подкласса, а не объектом класса родительского класса.
class Bar < Foo
end
p [Bar.a, Bar.b, Bar.c, Bar.d]
#=> [nil, nil, nil, nil]