Determine Class from Eigenclass
class, eigenclass, metaprogramming, ruby
Solution
Refining @BroiSatse's answer in a ruby-implementation-agnostic way,
class A; end
class B < A; end
class C < A; end
eigenclass = A.singleton_class
ObjectSpace.each_object(eigenclass).find do |klass|
klass.singleton_class == eigenclass
end
#=> A
This is also reliable when handling branches in subclass trees, the only reason why @Andrew Marshall's elegant answer doesn't work.
Problem
In Ruby, getting the eigenclass of a class `Foo` is a simple as ``` eigenclass = class << Foo; self; end #=> #<Class:Foo> eigenclass = Foo.singleton_class #2.1.0 #=> #<Class:Foo> ``` I'm interested in the inverse operation: getting the owner of the eigenclass from the eigenclass itself: ``` klass = eigenclass.owner #=> Foo ``` I'm not sure if this is possible, given that the eigenclass is an anonymous subclass of `Class`, so `Foo` appears nowhere in its inheritance hierarchy. Inspecting the method list of the eigenclass isn't encouraging either. `eigenclass.name` returns `nil`. The only thing that gives me hope this is possible: ``` Class.new # normal anon class #=> #<Class:0x007fbdc499a050> Foo.singleton_class #=> #<Class:Foo> ``` Clearly, the eigenclass's `to_s` method knows something about the owner, even if this information is hardcoded when the eigenclass is instantiated. Therefore the only method I'm aware of is some hacky `Object.const_getting` from that like ``` Object.const_get eigenclass.to_s[/^#\<Class\:(?<owner>.+)\>$/, :owner] #=> Foo ```