Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Ruby class name without class method

How can I get the class name of an instance of BasicObject in Ruby? For example, say I have this:

class MyObjectSystem < BasicObject
end
puts MyObjectSystem.new.class

How can I make this code succeed?

EDIT: I've found that Object's instance method class is defined as return rb_class_real(CLASS_OF(obj));. Any way to use this from Ruby?

like image 563
Jwosty Avatar asked Apr 03 '12 00:04

Jwosty


2 Answers

I spent some time playing around with irb and came up with this:

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

That will give any object that inherits from BasicObject a #class method that you can call.

Edit

Further explanation as requested in the comments:

Say you have object obj that is an instance of class Foo. obj gets its instance methods from those that are defined within the class Foo, in addition to the methods defined in Foo's parent class and so on up the inheritance chain. Ruby lets you define methods directly on an object that are only accessible to that particular object like this

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

obj.hello  #=> hello

other_obj = Foo.new
other_obj.hello  #=> Method missing error

The reason you can do this is because every object has something called a singleton class (or sometimes call an eigenclass) that you are actually defining the method on. This singleton class actually exists in the inheritance chain of the object directly beneath the object's actual class. That makes the object's actual class, Foo in this example, the superclass of the object's singleton class.

The class << self line you see in the answer is a special syntax for entering the scope of an object's singleton class. So in the example above, you could also define a method in an object's singleton class like this

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

obj.goodbye  #=> goodbye

So the line class << self; self; end is opening the object's singleton class (whatever object is currently self) and then returning self (self has now become the singleton class), which can then be assigned to a variable to do what you wish with.

I would recommend reading Metaprogramming Ruby if you want a better explanation of all this. It definitely gives you a much better understanding of the Ruby object model as a whole.

like image 76
Jeff Smith Avatar answered Oct 31 '22 23:10

Jeff Smith


I have to leave in a few minutes so I can't test it myself, but it seems like you could make a separate module that uses ffi to call rb_class_real from libruby. If I had more time I would test it first, but nobody else has answered yet and I don't want you leave you totally out in the cold.

like image 1
x1a4 Avatar answered Oct 31 '22 23:10

x1a4