Переменные экземпляра принадлежат объектам (экземплярам), поэтому они все-таки называются переменными экземпляра. Ваш первый @bar
является переменной экземпляра Foo
, ваш второй @bar
является переменной экземпляра только что созданного экземпляра Foo
. Это два совершенно разных объекта (они даже не одного класса: только что созданный экземпляр относится к классу Foo
, а Foo
— к классу Class
).
Очевидно, вам нужно увеличить @bar
в методе, вызываемом для Foo
, а не в методе, вызываемом для экземпляров Foo
. Итак, можем ли мы подумать о методе, который а) вызывается Foo
и б) вызывается каждый раз при создании экземпляра? А как насчет new
?
class Foo
@bar = 0
def self.new(*)
@bar += 1
super
end
end
Хорошо, с технической точки зрения, здесь не учитывается количество экземпляров, а только количество вызовов new
. Иногда экземпляры создаются без вызова new
, например. при десериализации. Это должно быть самое близкое, что вы можете получить, не прибегая к уродливым хакам внутренностей интерпретатора.
Вы можете подумать, что вместо этого можно переопределить allocate
(я тоже так думал), но я только что проверил это, и это не работает. Предположительно, реализация new
по умолчанию не вызывает allocate
обычными средствами, а фактически напрямую использует внутреннюю реализацию интерпретатора.
person
Jörg W Mittag
schedule
27.08.2015