Переменные экземпляра класса, как правило, более полезны и менее удивительны, чем переменные класса, поэтому вам, вероятно, следует использовать их.
А теперь я объясню некоторые вещи в мучительных деталях, которые вы ожидаете от ответа Ruby на StackOverflow:
Чтобы объявить или сослаться на переменную экземпляра класса, вы должны находиться в области действия класса и использовать один знак @. Это помещает переменную в экземпляр класса-одиночки для этого класса.
К сожалению, когда вы находитесь в области класса и используете ключевое слово def
, ваши методы помещаются в список методов экземпляра для этого класса и выполняются в области действия экземпляра, поэтому их переменные @-знака будут в экземпляре, в котором они находятся.
Вместо этого мы хотим определить методы для класса, а не для его экземпляров. На самом деле это означает, что эти методы находятся в списке методов экземпляра для класса-одиночки объекта класса. (Фу!)
Итак, подведем итог: существует по крайней мере четыре идиомы для переключения и определения методов в одноэлементном классе объекта класса 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
и тому подобное, но пока это должно вас удовлетворить. :-))
Последнее замечание: переменные экземпляра класса доступны только через класс, в котором они определены. Если вы попытаетесь вызвать любой из этих методов из (или через) подкласса, методы будут выполняться, но все переменные @ будут нулевыми, поскольку self
будет объектом класса подкласса, а не объектом класса родительского класса.
class Bar < Foo
end
p [Bar.a, Bar.b, Bar.c, Bar.d]
#=> [nil, nil, nil, nil]
person
AlexChaffee
schedule
28.09.2011