你如何找出单例类属于哪个类?

时间:2016-03-13 20:20:24

标签: ruby metaprogramming

假设我在变量#<Class:A>中有A(这是var的单例类),我想var.some_functionA作为其结果,红宝石中是否存在这样的功能? 显然,这样做的一种方法是Object.const_get var.to_s.split(':')[1].split('>')[0]但红宝石中有更好的方法还是现有的功能?

请允许我进一步澄清我的问题!

class A
    class << self
        p self
    end
end

给了我哪个是A.的单身类。我想要的是

class A
    class << self
        p self.some_thing
    end
end

给我A(准确地说是A级)。

3 个答案:

答案 0 :(得分:2)

首先:单身类不属于类,属于对象。 (当然,类对象。)

找到属于单例类的对象的唯一方法是迭代对象内存中的每个对象并检查其单例类:

foo_singleton_class = class << (foo = Object.new); self end

this_is_foo = ObjectSpace.each_object.detect {|obj| 
  begin
    obj.singleton_class == foo_singleton_class
  rescue TypeError => e
    raise unless e.message == "can't define singleton"
  end
}

foo.equal?(this_is_foo)
# => true

另请参阅Ruby问题跟踪器上的Feature #12084 Class#instance,该跟踪器在未来版本的Ruby中请求这样的方法作为功能增强。

答案 1 :(得分:0)

如果var包含对单例类的引用,则可以使用var.superclass来获取基类。

class A
end

obj = A.new
var = obj.singleton_class
#=> #<Class:A>

var.superclass
#=> A

答案 2 :(得分:0)

如果已知该类是模块的单例类(例如,类的实例),则可以执行此操作:

class A; end
k = A.singleton_class

ObjectSpace.each_object(Module).find { |klass| klass.singleton_class == k }
然而,@Jörg的答案更好,因为它不限制给出单例类的对象类型。