Reputation: 10613
In the following code delegate
refers the List
instance on which the closure is called. How was it set?
List.metaClass.removeRight = { int index ->
delegate.remove(delegate.size() - 1 - index)
}
Upvotes: 0
Views: 388
Reputation: 84786
Here is nice article on the topic. Especially Closures and the ExpandoMetaClass section.
I suppose that this
and owner
is ConsoleScript7@5e3eed51
because it's where the closure is declared.
Why delegate is equal to the list instance is well described in the mentioned article. Every class has an ExpandoMetaClass instance that surrounds it. This enables meta programming (e.g. adding methods, even if class is marked final), because method is being added to EMC which intercepts the call. A call hits the EMC first but it also needs access to surrounded instance and here's why the delegate is set to surrounded instance.
delegate
is set exactly in this (line 77) class when the added method is invoked. For the method You added an instance of ClosureMetaMethod
is created and registered with MOP. When it gets invoked the delegate is set to the object passed on which it's invoked. Is that now clear for You?
Upvotes: 1
Reputation: 27220
The MOP is responsible for dispatching method invocations to the closure. It (the MOP) retrieves the closure from the metaClass, clones it, sets the delegate to be the object that the method was invoked on, and then invokes the closure.
Upvotes: 1