Why is the method not closed on the class object?

In groovy, it's pretty easy to create a method closure, for example:

groovy:000> p = 1.&plus ===> org.codehaus.groovy.runtime.MethodClosure@a7981d5 groovy:000> p(3) ===> 4 

However, for some reason, it does not work when trying to use an instance of Class :

 groovy:000> List.isInstance([]) ===> true groovy:000> t = List.&isInstance ===> org.codehaus.groovy.runtime.MethodClosure@31ca1a68 groovy:000> t([]) ERROR groovy.lang.MissingMethodException: No signature of method: java.util.List.isInstance() is applicable for argument types: (java.util.ArrayList) values: [[]] at groovysh_evaluate.run (groovysh_evaluate:2) ... groovy:000> t = List.class.&isInstance ===> org.codehaus.groovy.runtime.MethodClosure@7b34c5ff groovy:000> t([]) ERROR groovy.lang.MissingMethodException: No signature of method: java.util.List.isInstance() is applicable for argument types: (java.util.ArrayList) values: [[]] at groovysh_evaluate.run (groovysh_evaluate:2) ... 

It is fairly easy to get around this, but I would like to understand why this is happening. Is there something in the MOP that stops this from working, etc.?

+4
source share
1 answer

When you use the method pointer in an instance of Class , then it must explicitly use the doCall() method provided by MethodClosure , instead of using call() by default << 24>.

doCall method from MethodClosure overrides the Closure doCall and intercepts the method call using invokeMethod instead of calling call() from Closure .

MethodClosure will also work if you explicitly use InvokerHelper , which is a synonym for doCall in MethodClosure or just a metaClass List.

 import org.codehaus.groovy.runtime.InvokerHelper t = List.&isInstance assert t.owner.simpleName == 'List' assert t.doCall([]) == true assert InvokerHelper.getMetaClass(t.owner). invokeStaticMethod(t.owner, 'isInstance', []) == true assert List.metaClass.invokeStaticMethod(t.owner, 'isInstance', []) == true 

invokeStaticMethod MOP is used if the object is an instance of Class .

&plus , on the other hand, works accordingly because the method pointer is created on a POJO.

+3
source

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


All Articles