On closures and groovy builder pattern -
starting grasp closures in general , groovy features.
given following code:
class mailer { void to(final string to) { println "to $to" } void from(final string from) { println "from $from" } static void send(closure configuration) { mailer mailer = new mailer() mailer.with configuration } } class mailsender { static void sendmessage() { mailer.send { 'them' 'me' } } } mailsender.sendmessage()
what happens under hood when pass closure mailer.send
method?
does to
, from
passed arguments closure point of view? types closure maps them?
and inside mailer.send
method @ moment mailer object calls mailer.with
receiving configuration
object, object maps them method calls. groovy reflection?
groovy can dynamically define delegate of closure , this
object.
with
setting delegate , executing closure. verbose way achieve same:
def math = { given 4 sum 5 print } class printmath { def initial def given(val) { initial = val } def sum(val) { initial += val } def getprint() { println initial return initial } } math.delegate = new printmath() math.resolvestrategy = closure.delegate_only assert math() == 9
what happens under hood when pass closure mailer.send method?
it receives not-yet-executed block of code.
does , passed arguments closure point of view?
no, better thinking of them anonymous class/lambda in java, or function(){}
in javascript.
which types closure maps them?
none, method calls waiting executed. can delegated different objects, though.
and inside mailer.send method @ moment mailer object calls mailer.with receiving configuration object, object maps them method calls. groovy reflection?
you can decompile groovy class file see going on. iirc, groovy uses "reflector" strategy (with arrayofcallsite
caching) make calls faster or can use invokedynamic
.
the closure math
in code above result in class:
// .. lot of techno-babble public object docall(object it) { callsite[] arrayofcallsite = $getcallsitearray(); arrayofcallsite[0].callcurrent(this, integer.valueof(4)); arrayofcallsite[1].callcurrent(this, integer.valueof(5)); return arrayofcallsite[2].callgroovyobjectgetproperty(this); return null; }
Comments
Post a Comment