Memahami Closure Di Groovy


Groovy memungkinkan developer untuk mendefinisikan closure, misalnya seperti pada kode program berikut ini:

class Latihan {
  def sebuahClosure = {
    println "Ini di dalam closure"
  }
}

def latihan = new Latihan()
latihan.sebuahClosure()

// outputnya adalah:
// Ini di dalam closure

Salah satu yang hal yang bisa menjebak adalah fakta bahwa def sebuahClosure adalah sebuah variabel yang menampung closure, bukan sebuah method!  Biar lebih jelas, saya akan menambahkan sebuah method di class tersebut sehingga terlihat seperti pada kode program berikut ini:

class Latihan {
  def sebuahClosure = {
    println "Ini di dalam closure"
  }

  void sebuahMethod() {
    println "Ini di dalam method"
  }
}

def latihan = new Latihan()
latihan.sebuahClosure()
latihan.sebuahMethod()

// outputnya adalah:
// Ini di dalam closure
// Ini di dalam method

Loh, terus apa bedanya sebuah closure dan sebuah method biasa?  Biar jelas, saya akan mengubah definisi class di atas menjadi seperti berikut ini:

class Latihan {
  def sebuahClosure = {
    println "Ini di dalam closure"
  }

  void sebuahMethod() {
    println "Ini di dalam method"
  }

  void proses(Closure argumen) {
    print "PROSES: "
    argumen()
  }
}

def latihan = new Latihan()

Berdasarkan kode program di atas, bila saya memberikan perintah seperti berikut ini:

latihan.proses(latihan.sebuahClosure)

Saya akan memperoleh hasil berupa:  PROSES: Ini di dalam closure. Hal ini memperlihatkan bahwa saya dapat melewatkan sebuah closure sebagai argumen dalam sebuah method karena closure tersebut di-“simpan” oleh sebuah variabel.

Tetapi bila saya memberikan perintah berikut ini:

latihan.proses(latihan.sebuahMethod)

Saya akan mendapatkan pesan kesalahan!!!  Apakah tidak bisa melewatkan sebuah method sebagai argumen?  Bisa, tetapi harus dalam bentuk seperti berikut ini:

latihan.proses(latihan.&sebuahMethod)

Bagaimana bila sebuah closure memiliki parameter?  Saya dapat menggunakan operator -> untuk memberikan parameter pada closure.   Hal ini terlihat pada kode program berikut ini:

def tambah = { nilai1, nilai2 ->
  println "${nilai1} + ${nilai2} = ${nilai1+nilai2}"
}

def kurang = { nilai1, nilai2 ->
  println "${nilai1} - ${nilai2} = ${nilai1-nilai2}"
}

void proses(nilai1, nilai2, Closure argumen) {
  print "PROSES: "
  argumen(nilai1, nilai2)
}

proses(10, 20, tambah)
proses(40, 30, kurang)

// Hasilnya adalah:
// PROSES: 10 + 20 = 30
// PROSES: 40 - 30 = 10

Ok, saya akan mengingat ini bila suatu saat nanti saya menemukan kode program dengan operator ->.

Btw, saya juga sering menemukan apa yang disebut dengan inline closure.  Melanjutkan dari kode program di atas, saya menambah baris seperti berikut ini:

proses(10, 20, tambah)
proses(40, 30, kurang)
proses(50, 60) {  nilai1, nilai2 ->
  println("${nilai1} * ${nilai2} = ${nilai1*nilai2}"
}

// Hasilnya adalah:
// PROSES: 10 + 20 = 30
// PROSES: 40 - 30 = 10
// PROSES: 50 * 60 = 3000

Bila parameter terakhir adalah sebuah Closure, saya dapat langsung memberikan definisi closure tersebut setelah pemanggilan method.

Berbekal pemahaman berdasarkan contoh di atas, saya akhirnya bisa memahami contoh kode program Griffon yang awalnya seolah penuh blok ajaib, misalnya yang terlihat berikut ini:

void mvcGroupInit(Map args) {
  ...
  execOutsideUI {
     String text = model.loadedFile.text
     execInsideUIAsync {
        model.fileText = text
     }
  }
}

Perihal Solid Snake
I'm nothing...

Apa komentar Anda?

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: