MetaClass/Delegate warning
I’ve been working like a fiend on Chama and am just about ready for an alpha release (not much but will have some basic model and dao creation from a groovy dsl paired with database goodness). Like a good programmer I have been building stuff up in chunks so that I can test everything separately and now this morning I started finally integrating everything together and blammo! something strange was happening.
The first part of this puzzle lies in QueryBuilder.groovy, this class is a builder that eventually will get called from inside of a finder method (like findAll()) and get parsed by another meta class, but more on that in a minute. Inside of QueryBuilder I do some checks on whether we are passing a closure or not, if we are then I set the delegate class to the current QueryBuilder instance and call the closure. Thus, when the closure continues processing the next interior method of the closure gets called it calls the QueryBuilder again allowing me to create new restrictions inside the current criteria. Running my tests and everything works as expected. Now for the strange part.
In the next part I created a new class JavaModelDAOBuilder.groovy which will actually parse a Groovy script and call each method in turn through a custom meta class called MethodInterceptor. This meta class has now essentially taken first responder position to any method calls that happen on the Groovy script. Which actually sounds good on the surface, until I discovered that a closure is actually “owned” by its class. Now that the class has a meta class it will intercept all calls to the closure, completely bypassing the delegate.
After some digging I can see how this makes sense and after sending a message to the list I got some great responses. The final solution that Jochen(Blackdrag) came up with is to set a flag so that meta classes can “delegate” to another delegate. I think that this is definitely a workable solution, but for now I have some kind of hacky solution in the MethodInterceptor so that it looks for anything that the delegate should actually be handling and pass it back to that instance.
The good news is that it looks like this will be fixed in the near future, for those of us really pushing Groovy’s Meta Object Programming (MOP) and I think I’m going to be joining the dev list so that I can watch those conversations (especially the MOP-related ones). On another note I’m working on a few more Meta-related posts that will hopefully be of interest to some people ;-).
Trackbacks
Use the following link to trackback from your own site:
http://www.warneronstine.com/blog/articles/trackback/294
