0

我正在扩展BasicObject,我想实现Object#class方法。除了像这样对返回值进行硬编码之外,我不确定如何执行此操作:

class MyObject < BasicObject
  def class
    ::Kernel::eval "::MyObject"
  end
end

MyObject.new.class
#=> MyObject

使用此解决方案,任何继承自的类MyObject都必须覆盖此方法以保持其准确性。有没有更好的办法?

4

3 回答 3

2

在 Ruby 中无法实现此方法。您需要访问 Ruby 无法访问的三项内容:

  • 类指针
  • 超类指针
  • 虚拟类标志(包括类和单例类是虚拟类)

Object#class像这样工作:

class Object
  def class
    c = self.__class__
    c = c.__superclass__ while c.__virtual__?
    c
  end
end

还有Class#superclass

class Class
  def superclass
    c = self.__superclass__
    c = c.__superclass__ while c.__virtual__?
    c
  end
end

而且由于无法获取类指针(请记住:该class方法不会返回它)并且无法获取超类指针(请记住:该superclass方法也不会返回它)并且您没有办法要检查一个类是否是虚拟的,用 Ruby 编写这个方法是不可能的。

您需要对运行时内部进行某种特权访问才能做到这一点。

于 2013-07-20T04:09:30.613 回答
0

我被引导到这个可能重复的问题:如何获取 BasicObject 实例的类?

为该问题提供的解决方案解决了我的问题。谢谢!

于 2013-07-20T05:29:21.787 回答
0

由于您拒绝继承Object,因此您几乎缺少所有基本方法,包括classor ancestors。您需要对所有内容进行硬编码。除了最小的语法,一切都消失了。把它想象成tabla rasa。没有其他方法可以构建您的方法。

Ruby 被设计为让所有对象都继承自Object,并且违背这一点不会产生有用的结果。

于 2013-07-20T04:08:16.853 回答