如何在 Ruby 中获取 BasicObject 实例的类名?例如,假设我有这个:
class MyObjectSystem < BasicObject
end
puts MyObjectSystem.new.class
我怎样才能使这段代码成功?
编辑:我发现 Object 的实例方法class
被定义为return rb_class_real(CLASS_OF(obj));
. 有什么方法可以从 Ruby 中使用它?
如何在 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
您可以调用的方法。
编辑
评论中要求的进一步解释:
假设您有一个 objectobj
是 class 的实例Foo
。除了在 的父类中定义的方法之外,还obj
从定义在 class 中的方法获取其实例方法,依此类推。Ruby 允许您直接在对象上定义方法,这些方法只能由该特定对象访问,如下所示Foo
Foo
obj = Foo.new
def obj.hello
puts "hello"
end
obj.hello #=> hello
other_obj = Foo.new
other_obj.hello #=> Method missing error
您可以这样做的原因是因为每个对象都有一个称为单例类(或有时称为特征类)的东西,您实际上是在其上定义方法。这个单例类实际上存在于对象的实际类下面的对象的继承链中。这使得对象的实际类,Foo
在本例中,是对象的单例类的超类。
您在答案中看到的那class << self
行是用于输入对象的单例类范围的特殊语法。所以在上面的例子中,你也可以像这样在对象的单例类中定义一个方法
class << obj
def goodbye
puts "goodbye"
end
end
obj.goodbye #=> goodbye
因此,该行class << self; self; end
打开对象的单例类(无论当前是什么对象self
)然后返回self
(self
现在已成为单例类),然后可以将其分配给一个变量来执行您希望使用的操作。
如果您想更好地解释这一切,我建议您阅读Metaprogramming Ruby 。它肯定会让您更好地理解整个 Ruby 对象模型。
我必须在几分钟后离开,所以我不能自己测试它,但看起来你可以制作一个单独的模块,使用ffirb_class_real
从 libruby调用。如果我有更多的时间,我会先测试它,但还没有人回答,我不想让你完全冷落。
根据 Jeff Smith 的回答,您无需修改即可执行此操作BasicObject
:
class << object; self; end.superclass
哪里object
是您想要的类的对象的实例,即
irb(main):001:0> object = BasicObject.new
(Object doesn't support #inspect)
=>
irb(main):002:0> class << object; self; end.superclass
=> BasicObject