【问题标题】:How do you findout what class a singleton class belongs to? [duplicate]你如何找出一个单例类属于哪个类? [复制]
【发布时间】:2016-03-13 20:20:23
【问题描述】:

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

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

class A
    class << self
        p self
    end
end

给我哪个是 A 的单例类。我想要的是

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

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

【问题讨论】:

  • 可能你记住self.class或类似的东西
  • 执行p var会返回什么?
  • 你知道A会提前吗? (我假设没有。)您能否提供更多相关的上下文来说明您如何创建单例类以及为什么需要原始类(以及为什么不能以其他方式获得它)?
  • 是的,我可以通过另一种方式得到它,就像我在发布的问题中提到的那样。我想知道,因为我想在我正在扩展的模块中定义一个方法。这个方法应该使用self.answer_to_my_question.define_method... 创建实例方法,我这样做是因为我想实现 DirtyObjects noob 风格。 :) 但是所有这些细节对我的问题没有帮助。
  • 有人试图在较低级别上执行此操作here

标签: ruby metaprogramming


【解决方案1】:

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

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

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 中使用这种方法作为功能增强。

【讨论】:

  • 很好的答案,包括对提议功能的引用。 foo_singleton_class = (foo = Object.new).singleton_class 可能会更好读一点。
【解决方案2】:

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

class A
end

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

var.superclass
#=> A

【讨论】:

  • 嗯..我试过了,它只是说Class
  • 对不起,我回答的有点仓促。请查看我的更新,它肯定会起作用!
  • 这将给出对象的单例类作为答案!
  • 两件事:1)您使用的是什么版本的 ruby​​,2)您确定 var 持有对单例类的引用,或者 var 是基于一个单例类(即您可能在对象上定义了一些不在原始类中的单例方法)?
  • 为了清楚起见,我已经编辑了我的问题,请重新阅读:)。
【解决方案3】:

如果已知类是模块的单例类(例如,相对于类的实例),您可以这样做:

class A; end
k = A.singleton_class

ObjectSpace.each_object(Module).find { |klass| klass.singleton_class == k }

不过,@Jörg 的答案更好,因为它不限制为其提供单例类的对象类型。

【讨论】:

  • 很好,但Object.const_get var.to_s.split(':')[1].split('&gt;')[0] 可能仍然比遍历所有这些对象更好:)。
猜你喜欢
  • 2011-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-29
  • 1970-01-01
  • 1970-01-01
  • 2010-12-28
  • 2013-12-01
相关资源
最近更新 更多