Alexander Suraphel
Alexander Suraphel

Reputation: 10613

Groovy: How is delegate of a closure set when adding a method on a metaclass of one class?

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

Answers (2)

Opal
Opal

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

Jeff Scott Brown
Jeff Scott Brown

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

Related Questions