У меня есть скрипт, который повторяется с использованием ObjectSpace#each_object
без аргументов.Затем он печатает, сколько экземпляров существует для каждого класса.
Я понял, что некоторые классы переопределяют метод экземпляра #class
, поэтому мне пришлось искать другой способ получить реальный класс;Допустим, он хранится в переменной "klass"
, а klass === object
- это истина.
В Ruby 1.8 я мог бы сделать это, предполагая, что Object
не был настроен как обезьяна:
Object.instance_method(:class).bind(object).call
Этоработал для ActiveSupport::Duration
экземпляров:
# Ruby 1.8
# (tries to trick us)
20.seconds.class
=> Fixnum
# don't try to trick us, we can tell
Object.instance_method(:class).bind(20.seconds).call
=> ActiveSupport::Duration
Но в Ruby 1.9 это больше не работает:
# Ruby 1.9
# we are not smart...
Object.instance_method(:class).bind(20.seconds).call
TypeError: bind argument must be an instance of Object
from (irb):53:in `bind'
from (irb):53
from /Users/user/.rvm/rubies/ruby-1.9.2-p0/bin/irb:17:in `<main>'
Оказывается, ActiveSupport::Duration
подклассы ActiveSupport::BasicObject
.Последний сделан для подкласса ::BasicObject
в Ruby 1.9, поэтому Object
исключен из цепочки наследования.Это не происходит и не может произойти в Ruby 1.8, поэтому ActiveSupport::BasicObject
является подклассом Object
.
Я не нашел способа обнаружить фактический класс объекта Ruby 1.9это не экземпляр Object
.BasicObject
в 1.9 - это действительно пустяки:
BasicObject.instance_methods
=> [:==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__]
Идеи?
ОБНОВЛЕНИЕ:
Поскольку ruby 1.9 достиг конца срока службы, я меняюсья принимаю @ косвенный ответ.Упомянутые выше рубины 1.9 приведены исключительно для исторических целей, чтобы показать, что первоначальное возникновение моей проблемы было изменением с 1.8 на 1.9.