ObjectSpace#each_object
迭代而不带参数。然后它会打印每个类存在多少实例。我意识到一些类重新定义了
#class
实例方法,所以我必须找到另一种获取实际类的方法;假设它存储在变量"klass"
中,并且klass === object
为true。在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。后者在Ruby 1.9中被设计为继承自::BasicObject,因此Object被排除在继承链之外。这在Ruby 1.8中无法实现,因此ActiveSupport::BasicObject是Object的子类。
我没有找到任何一种方法来检测不是Object实例的Ruby 1.9对象的实际类。1.9中的BasicObject真的很简单:
BasicObject.instance_methods
=> [:==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__]
有什么想法吗?
更新:
由于Ruby 1.9已到达生命周期终点,我将接受@indirect的答案。上述提到的Ruby 1.9仅用于历史目的,以显示从1.8到1.9的更改是我问题的根本原因。
__realclass__
而不是class
。 - Kelvin