Volume Groovy ExpandoMetaClass?

Groovy provides an ExpandoMetaClass that allows you to dynamically add instance and class methods and properties to POJO. I would like to use it to add an instance method to one of my Java classes:

 public class Fizz { // ...etc. } Fizz fizz = new Fizz(); fizz.metaClass.doStuff = { String blah -> fizz.buzz(blah) } 

This would be equivalent to Fizz class refactoring:

 public class Fizz { // ctors, getters/setters, etc... public void doStuff(String blah) { buzz(blah); } } 

My question is:

Does this doStuff(String blah) just this particular instance of Fizz ? Or do all Fizz instances now have a doStuff(String blah) instance method?

If first, how do I get all Fizz instances to use the doStuff instance doStuff ? I know that if I did Groovy:

 fizz.metaClass.doStuff << { String blah -> fizz.buzz(blah) } 

Then it will add a static class method to Fizz , for example Fizz.doStuff(String blah) , but this is not what I want. I just want all Fizz instances to now have an instance method called doStuff . Ideas?

+6
source share
1 answer

First, when you add Fizz to the main class, its instances do not receive the method, since the instances have already been counted and added to memory.

Thus, one way to approach this is to use the method signature from the source class. Therefore, instead of

fizz.doStuff(blah)

call the class method. therefore

fizz.&doStuff(blah)

Gets the method signature from the source class, but uses the attributes from the instance. However, as you can imagine, since it calls the calling class, this is a bit of a difficult call.

Now, one alternative to popping each instance is to make instances of ExpandoMetaClass instances for Fizz. Hence,...

 Fizz.metaClass.doStuff = {return "blah"} fizz = new Fizz() Fizz.metaClass.doOtherStuff = {return "more blah"} assert fizz.doOtherStuff() == "more blah" 

Hope this helps

UPDATE:

Full code example:

 class Fizz{ } Fizz.metaClass.doOtherStuff = {return "more blah"} def fizz = new Fizz() assert fizz.doOtherStuff() == "more blah" def fizz1 = new Fizz() assert fizz1.doOtherStuff() == "more blah" 
+3
source

Source: https://habr.com/ru/post/957536/


All Articles