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
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.