获取没有类方法的Ruby类名

Jwo*_*sty 5 ruby oop class object ruby-1.9.3

如何在Ruby中获取BasicObject实例的类名?例如,说我有这个:

class MyObjectSystem < BasicObject
end
puts MyObjectSystem.new.class
Run Code Online (Sandbox Code Playgroud)

如何使此代码成功?

编辑:我发现Object的实例方法class定义为return rb_class_real(CLASS_OF(obj));.有没有办法从Ruby使用它?

Jef*_*ith 8

我花了一些时间玩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
Run Code Online (Sandbox Code Playgroud)

这将为从BasicObject继承的任何对象提供一个#class可以调用的方法.

编辑

评论中要求的进一步解释:

假设你有obj一个类的实例对象Foo.除了在父类中定义的方法以及继承链上的方法之外,obj从类中定义的方法获取其实例方法.Ruby允许您直接在对象上定义方法,这些对象只能像这样访问特定对象FooFoo

obj = Foo.new
def obj.hello
  puts "hello"
end

obj.hello  #=> hello

other_obj = Foo.new
other_obj.hello  #=> Method missing error
Run Code Online (Sandbox Code Playgroud)

你可以这样做的原因是因为每个对象都有一个叫做单例类(或者有时称为本征类)的东西,你实际上是在定义方法.这个单例类实际上存在于对象的实际类正下方的对象的继承链中.这使得对象的实际类(Foo在此示例中为对象的singleton类的超类)成为可能.

class << self您在答案中看到的行是用于输入对象的单例类范围的特殊语法.所以在上面的例子中,你也可以像这样在对象的单例类中定义一个方法

class << obj
  def goodbye
    puts "goodbye"
  end
end

obj.goodbye  #=> goodbye
Run Code Online (Sandbox Code Playgroud)

所以这行class << self; self; end是打开对象的单例类(当前是什么对象self)然后返回self(self现在变成单例类),然后可以将其分配给变量以执行您想要的操作.

如果你想要更好地解释所有这些,我建议阅读Metaprogramming Ruby.它绝对可以让您更好地理解整个Ruby对象模型.

  • 哦,那很聪明! (3认同)