如何在 Ruby 中获取 BasicObject 实例的类名?例如,假设我有这个:
class MyObjectSystem < BasicObject
end
puts MyObjectSystem.new.class
我怎样才能使这段代码成功?
编辑:我发现 Object 的实例方法 class
被定义为 return rb_class_real(CLASS_OF(obj));
。有什么方法可以从 Ruby 中使用它?
最佳答案
我花了一些时间研究 irb 并想出了这个:
class BasicObject
def class
klass = class << self; self; end # get the object's singleton class
klass.superclass # the superclass of an object's singleton class is that object's class
end
end
这将为任何从 BasicObject 继承的对象提供一个 #class
您可以调用的方法。
编辑
评论中要求的进一步解释:
假设你有对象 obj
那是类 Foo
的一个实例. obj
从类 Foo
中定义的实例方法中获取实例方法, 除了 Foo
中定义的方法的父类等在继承链上向上。 Ruby 允许您直接在对象上定义方法,这些方法只能像这样访问该特定对象
obj = Foo.new
def obj.hello
puts "hello"
end
obj.hello #=> hello
other_obj = Foo.new
other_obj.hello #=> Method missing error
您可以这样做的原因是因为每个对象都有一个称为单例类(或有时称为特征类)的东西,您实际上是在其上定义方法。这个单例类实际上存在于对象的实际类的正下方的对象的继承链中。这使得对象的实际类,Foo
在此示例中,对象的单例类的父类(super class)。
class << self
您在答案中看到的一行是用于进入对象的单例类范围的特殊语法。所以在上面的例子中,你也可以像这样在对象的单例类中定义一个方法
class << obj
def goodbye
puts "goodbye"
end
end
obj.goodbye #=> goodbye
所以行 class << self; self; end
正在打开对象的单例类(无论对象当前是 self
)然后返回 self
(self
现在已经成为单例类),然后可以将其分配给一个变量来执行您想要的操作。
我会推荐阅读 Metaprogramming Ruby如果你想更好地解释这一切。它绝对能让您更好地理解整个 Ruby 对象模型。
关于ruby - 没有类方法获取 Ruby 类名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9985597/