从元类中获取实例

时间:2014-11-10 01:54:25

标签: ruby metaclass

给定ruby(或eigenclass或singleton_class)中的元类,我如何找到该类的实例?据我所知,元类与所述元类的SINGLE实例有内在联系。因此,应该有办法找到它的实例,对吗?

例如......

class Example
  def self.do_something
    "Hello everyone!"
  end
end

p Example #should output 'Example'
p Example.singleton_class #should output '#<Class:Example>'

我想要一个可以执行以下操作的方法:

def meta_do_something(meta)
  #invokes the do_something method on the object that meta references
end

meta_do_something(Example.singleton_class) #should output "Hello everyone!"

我一直在四处寻找,但我什么都找不到......有什么想法吗?

1 个答案:

答案 0 :(得分:1)

类(在您的情况下为示例)不是其单例类的实例。这是一个子类。子类不是它们的超类的实例,它们只是......好吧,子类。实例是使用SomeClassSomeClass.new创建的对象。 Ruby使元类不可见的原因是有原因的。我想你的基本问题基本上是一个超级班是否可以知道它的子类,答案是否定的,我想这会破坏很多OOP概念(狗是动物,但不是每个动物都是一只狗)。

确实do_something是Singleton类的实例方法(所有方法都是Ruby技术上讲的实例方法),但事实是你不能像初始化一样初始化一个新的Singleton类。任何其他类。这就是为什么Ruby使这个类不可见(通过调用.ancestors无法看到)。

编辑:如果您不惜一切代价这样做,这是一个(丑陋的)黑客攻击工作:

def meta_do_something(meta)
  actual_class = Object.const_get(meta.to_s[/(?<=#<Class:)[^>]+/])
  method_to_call =  meta.instance_methods(false)[0]
  actual_class.send(method_to_call)
end

meta_do_something(Example.singleton_class) #=> "Hello everyone!"

如果你想调用单例类中定义的所有方法,你可以这样做(替换第3行和第4行):

meta.instance_methods(false).each do |method|
    actual_class.send(method)
end