MetaProgramming with MetaClass

24 / Sep / 2012 by Amit Kumar 2 comments

As we all know that groovy is a dynamic programming language, so we can add any method to any class at runtime. First, let’s see a small and simple example of metaProgamming given below, in which we are adding a method (isEvent) into an Integer class.

Integer.metaClass.isEven = { -> // only (->) sign indicates that isEven() method is no argument method
    delegate%2 == 0
}

When we see the above program few questions arise in our mind, what is metaClass? What is delegate?? How metaprogramming is actually working?? How to disable MetaProgramming?? isEven() method a static or instance method?? etc… Let’s move on to every question one by one.

1. What is metaClass?? In Groovy Language, every object has an object of MetaClass class with name metaClass. This metaClass object is responsible for holding all the information related to that object. Whenever you perform any operation on that object, Groovy’s dispatch mechanism routes the call through that Metaclass object(metaClass). So if you want to change the behaviour of any object/class, you will have to alter the MetaClass object attached to that class/object, and it will alter the behaviour of that class/object at run time.

2. What is delegate?? We can say delegate is reference of that object who is invoking that isEven() method.

3. How metaprogramming is actually working?? Whenever we call a method of class/object, it first gets information of that object from metaClass attached to it, and then calls the appropriate method. In above program we are asking Integer metaClass, that there is an isEven() method in integer class, whose definition is followed by it. Now when we will call “anyInteger.isEven()”, it will excute isEven() method and will return true/false accordingly, e.g.

9.isEven() // false
8.isEven() // true

4. How to disable MetaProgramming?? Once a method is added into any class/object, that method will be available in complete application. If you want remove that method from a particular situation you will have to assign null into Integer.metaClass. e.g.

Integer.metaClass = null
7.isEven() // will throw MissingMethodException

5. isEven() method is static or instance method?? isEven() is an instance method. To add a static method at run time, you will have to follow signature given below:

Integer.metaClass.static.isEven = { number ->
    number%2 == 0
}
Integer.isEven(1) // false
Integer.isEven(2) // true

6. isEven() method is added to that object only?? No, isEven() method is added to all the Integer objects, if we want to add isEven() in a particular object only then we have to use that object reference .metaClass instead of Integer.metaClass, e.g.

Integer aNumber = 9
aNumber.metaClass.isEven = { ->
    delegate%2 == 0
}
println aNumber.isEven() // false
println 2.isEven() // will throw MissingMethodException.

7. How to add multiple methods?? To add the multiple method into single class see below example:

Integer.metaClass {
    isEven { -> delegate%2 == 0 }
    isOdd { -> delegate%2 != 0 }
    // other methods
}

println 6.isEven() // true
println 6.isOdd()  // false

More Blogs by Me

FOUND THIS USEFUL? SHARE IT

comments (2)

Leave a comment -