Reputation: 751
I implemented methodMissing() for my groovy class and then added the intercepted method to MetaClass. Assumption is that after first call to non-implement method, next time it won't invoke methodMissing(). But, it's not working like that. Instead, methodMissing is getting called every time.
Below is code snippet:
class MyDeveloper {
List lang = []
def methodMissing(String name, args) {
println "$name method was called"
if(name.startsWith("write")) {
String language = name.split("write")[1]
if( lang.contains(language) ) {
def myImpl = { Object[] theArgs ->
println "love to write code in $language"
}
MyDeveloper.metaClass."$name" = myImpl
return myImpl(args)
}
}
}
}
MyDeveloper n = new MyDeveloper()
n.lang << "Groovy"
n.lang << "Java"
n.writeGroovy()
n.writeGroovy()
n.writeGroovy()
n.writeJava()
n.writeJava()
O/P:
writeGroovy method was called
love to write code in Groovy
writeGroovy method was called
love to write code in Groovy
writeGroovy method was called
love to write code in Groovy
writeJava method was called
love to write code in Java
writeJava method was called
love to write code in Java
Expected O/P:
writeGroovy method was called
love to write code in Groovy
love to write code in Groovy
love to write code in Groovy
writeJava method was called
love to write code in Java
love to write code in Java
I am using:
➜ ~ groovy -v
Groovy Version: 3.0.4 JVM: 1.8.0_252 Vendor: AdoptOpenJDK OS: Mac OS X
➜ ~ java -version
openjdk version "1.8.0_252"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_252-b09)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.252-b09, mixed mode)
Upvotes: 0
Views: 154
Reputation: 20699
You are missing a piece in the constructor to enable "caching":
class Dev {
Dev(){
def mc = new ExpandoMetaClass(Dev, false, true)
mc.initialize()
this.metaClass = mc
}
def methodMissing(String name, args) {
println "$name method was added"
def myImpl = { Object[] a -> println ">> $name, $a" }
this.metaClass."$name" = myImpl
myImpl args
}
}
def d = new Dev()
d.en 'a'
d.de 'b'
d.de 'b'
And it prints:
en method was added
>> en, [a]
de method was added
>> de, [b]
>> de, [b]
Upvotes: 3