Friday, November 10, 2006

Using reflection in Ruby

Reflection in Ruby is a great way of doing the things at runtime. Sometimes you need to create an instance of class depending upon the parameter passed to a function. This parameter could be the name of the class to be created.

One way to do this is to write conditional loops and create the object. But if there are too many classes then this would become messy. Here comes reflection to rescue.

In Ruby using reflection you can get the following information:
1, What all class currently exists?
2. Their methods information
3. Their class hierarchy and lot more

Let consider the above problem and try to find out the solution using Reflection.

Ruby provide a module called "ObjectSpace" that lets you to use reflection and see all the above mentioned information.

so if you say

ObjectSpace.each_object { |x| puts x }


It will print all living, nonimmediate objects in Ruby process.
If you specify the type of objects that you want then you can specify it as option to each_object method. So,

ObjectSpace.each_object(Class) { |x| puts x}


will print all the classes that are there in the Ruby process.

So now the above problem becomes simple.
Iterate over all the classes compare their name. If name matches then create object and execute whichever function you like.

So, the code looks like

class ClassFromString
@@counter = 0
def initialize
@@counter += 1
end
def getCounterValue
puts @@counter
end
end


def createClassFromString(classname)
ObjectSpace.each_object(Class) do |x|
if x.name == classname
object = x.new
object.getCounterValue
object = x.new
object.getCounterValue
end
end
end
createClassFromString("ClassFromString")


Once you get the object you can use any method of that object. For e.g. you can use superclass method to get the name of the parent class and so on and can build complete hierarchy dynamically.
You can get the information about methods of a given class using methods like private_methods(), protected_methods() which are defined in Object class which is base class for each object.

Reflection is great thing but there is also some performance hit when you use Reflection.

Happy programming !!!

6 comments:

Prema said...

I am very new to this language and the concept reflection looks interesting to me with interpreted language like Ruby....

Linh Nguyen (nguyenlinh@hotmail.com) said...

i too am new to the ruby language. my question is how do you create an object if the class is defined in another file?

in java for instance a class must correspond to file name className.java, but in ruby there's no such restriction. how do you know which file to "require" in order to create an object?

Angrez Singh said...

In ruby you need to give the name of the file or path of the file in which your class is declared in the "require" statement. The path of the file is relative to the file in which you are creating the instance.

For more information visit the following site:
http://www.ruby.ch/ProgrammingRuby/htmlC/

Anonymous said...

Amiable brief and this post helped me alot in my college assignement. Gratefulness you for your information.

anbu said...

Hi Can You tell me the real time example to this reflection.am new to ruby.what is the use of reflection and which place we can to use this ?


And we can implement this one in rails.

anbu said...

can you give real time example to this reflection? And can we implement in rails?