2

I am looking for a way to get the instance of an eigenclass, since each eigenclass has only one instance.

I could look thru ObjectSpace be testing each eigenclass, but I guess it's expensive.

Curiously, I must get the eigenclass of each object to test the match, because is_a? does not suffice:

class A; end
class B < A; end

AA = class << A; self; end

p A.is_a? AA #=> true
p B.is_a? AA #=> true!!!!

I wish there was an Class#instance or Class#instances method to get the instance(s) of a class (or eigenclass).

The most direct way would be extract the instance from the eigenclass' inspect, but I'm wondering if I can rely on it:

p AA         #=> #<Class:A>
instance = Object.const_get(AA.inspect.match(/^#<Class:(\w+)>$/)[1])
p instance   #=> A

# (this works for class' eigenclass)

My use case is that I must get the class of a class method, but the Method#owner gives me the eigenclass, and Method#receiver gives me the current receiver:

# Continuing previous example
def A.f; end
mtd = B.method(:f)
p mtd.owner     #=> #<Class:A>
p mtd.receiver  #=> B
# I want to obtain A

Any ideas?

Sony Santos
  • 5,435
  • 30
  • 41

1 Answers1

6

If you want to find instances of any given class, you can use ObjectSpace:

class A; end
class B < A; end

ObjectSpace.each_object(A.singleton_class).to_a
# => [B, A]
Matheus Moreira
  • 17,106
  • 3
  • 68
  • 107
  • What is method `singletonclass`? – sawa Jan 10 '13 at 19:57
  • 1
    @sawa, see the [`Object#singleton_class` method documentation](http://www.ruby-doc.org/core-1.9.3/Object.html#method-i-singleton_class). – Matheus Moreira Jan 10 '13 at 20:00
  • Great. I didn't know such method existed. Now, I can use it. – sawa Jan 10 '13 at 20:24
  • 1
    Good to know `singleton_class` (which doesn't work in 1.8.7 BTW, but I always can use `class << A; self; end` when needed). Your answer showed that the problem is far less complicated than I imagined. To obtain `A` I can use `ObjectSpace.each_object(A.singleton_class).to_a.last`. Thank you! – Sony Santos Jan 11 '13 at 01:23
  • Not gonna to work on jruby, at least with disabled `ObjectSpace` by default – Waterlink Jan 14 '15 at 01:07
  • Given it is a singleton class, doesn't `A.singleton_class` return that single instance? Why need to scan object space? – akostadinov Mar 10 '21 at 19:13
  • @akostadinov Because subclasses of the class are also instances of its singleton class. – Matheus Moreira Oct 21 '21 at 07:52
  • I actually confused the original question so my own question does not make much sense I see :) – akostadinov Oct 21 '21 at 15:00