KnowledgeHub
Questions
Tags
Users
Search
Alex Rivera
|
Logout
Edit Question
Title
Body
I have a script that iterates using ObjectSpace#each_object with no args. Then it prints how many instances exist for each class. I realized that some classes redefine the #class instance method, so I had to find another way to get the actual class; Let's say it's stored in variable "klass" , and klass === object is true. In Ruby 1.8 I could do this, assuming Object wasn't monkeypatched: Object.instance_method(:class).bind(object).call This worked for ActiveSupport::Duration instances: # 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 But, in Ruby 1.9 this no longer works: # 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>' It turns out that ActiveSupport::Duration subclasses ActiveSupport::BasicObject . The latter is made to subclass ::BasicObject in Ruby 1.9, so Object is excluded from the inheritance chain. This doesn't, and can't, happen in Ruby 1.8, so ActiveSupport::BasicObject is a subclass of Object . I haven't found any way to detect the actual class of a Ruby 1.9 object that isn't an instance of Object . BasicObject in 1.9 is really bare-bones: BasicObject.instance_methods => [:==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__] Ideas? UPDATE: Since ruby 1.9 reached end-of-life, I'm changing my accept to @indirect's answer. The mentions of ruby 1.9 above are
Tags (comma-separated)
Save Edits
Cancel