Wednesday, May 14, 2008

delegate ใน groovy closure

งาน NJUG ที่ผ่านมาตอนที่ฟังคุณ cblue พูดเรื่อง groovy
มีตัวแปรใน closure ตัวหนึ่งที่ผมติดใจ ก็คือ delegate
กลับมาแล้วก็เลยต้องนั่งเปิด groovy document หาความรู้เพิ่มเติม
ก็เลยเจอ snippet code ที่น่าสนใจตัวนี้เข้า

เทคนิคที่น่าสนใจก็คือการเปลี่ยน reference ของ delegate ให้ชี้ไปยัง object ที่เราต้องการ

class XmlBuilder {
def out
XmlBuilder(out) { this.out = out }
def invokeMethod(String name, args) {
out << "<$name>"
if(args[0] instanceof Closure) {
args[0].delegate = this
args[0].call()
}
else {
out << args[0].toString()
}
out << "</$name>"
}
}

ลองดูตัวอย่างการ run code ข้างบน
จะเห็นว่ามีการใช้ closure ซ้อนๆกัน

def xml = new XmlBuilder()
xml.html {
head {
title "Hello World"
}
body {
p "Welcome!"
}
}

ทุกๆครั้งที่ มีการ execute inner closure ก็จะมีการ switch delegate ให้ชี้ไปที่
XmlBuilder Object แทนที่จะเป็น default parent object

Related link from Roti

3 comments:

นายข้าวโพดหวาน said...

เห็นโค้ดแล้ว สงสัยว่าเค้าสร้าง closing tag ตรงไหนหรือครับ

polawat phetra said...

แก้ให้แล้วครับ ผมลืม encode พวก "<" กับพวก ">" ใน source น่ะครับมันก็เลยไม่ render

Sand said...

OFBiz เค้าใช้ Groovy เป็น script แล้วนะครับ