Feature #6682
Add a method to return an instance attached by a singleton class
Description
=begin
Currently, there is no easy way to get the attached instance from a singleton class. For MRI, we have to resort to writing an C extension. So it'll be useful to add an instance method to Class to return the attached instance if the given class object is a singleton class.
I'll show what I want in the code-wise with the following code snippet:
text = "I love Ruby."
klass = text.singleton_class
# => #Class:#<String:0x000000027383e8>
klass.singleton_instance # <= This is the new method.
# => "I love Ruby."
String.singleton_instance # <= This should return nil because String isn't a singleton class and there is no singleton instance, rather there will be many instances.
# => nil
As for use cases, in my case, I wanted to create a module to add class methods. And it has some state, so must be initialized properly. And it can equally be used by Class#extend and Class#include like this:
module Countable
attr_reader(:count)
class << self def extended(extended_class) p("extending #{extended_class}") super initialize_state(extended_class) end def included(included_class) p("including #{included_class}") super if included_class.singleton_instance # <= Currently, I can't do this. initialize_state(included_class.singleton_instance) end end private def initialize_state(object) p("initializing state of #{object}") object.instance_variable_set(:@count, 0) end end
end
class Person
extend(Countable)
end
class Book
class << self
include(Countable)
end
end
p(Person.count)
p(Book.count)
# => "extending Person"
# => "initializing state of Person"
# => "including #Class:Book"
# => "initializing state of Book"
# => 0
# => 0
Others wanted this functionality as shown by (()). Also, I found several actual C-extensions for this kind of functionality on the wild browsing (()) on github.
- (())
- (())
Thanks for creating a great language. Especially I love its meta-programming capability. I'd wish this feature to lead to better meta-programming capability of Ruby.
=end
Files