简体   繁体   中英

Creating Global Groovy Closure

I'm trying to learn how to create a global closure in groovy (like the println closure). I have the following code:

a.groovy

def header = Tools.&header
header 'groovy script a'

b.groovy

def header = Tools.&header
header 'groovy script b'

tools.groovy

class Tools {
    def static header(String str) {
        println("\n${str}")
        println("-" * 80)
    }
}

I would like to avoid:

def header = Tools.&header

in every groovy script where I would like to use the Tools.header() (and just use header closure when I import the tools package). I tried to put the definition after the Tools class, but that did not work. Can this be done? Is there a better way to handle this?


EDIT: (using a metaClass and the evaluate method unless there is a simpler way to include an external script):

a.groovy

evaluate(new File("Tools.groovy"))
header 'groovy script a'

b.groovy

evaluate(new File("Tools.groovy"))
header 'groovy script b'

tools.groovy

Object.metaClass.header = {str ->
    println("\n${str}")
    println("-" * 80)
}

println is not actually a global closure. It's a method that is added to java.lang.Object using groovy metaprogramming. Because all classes extend Object - including the script class that wraps code run in the groovy console - println can be called from anywhere.

You can add your own methods to Object . Run this code in the Groovy console to see it in action:

// Add a global sayHello() method
Object.metaClass.sayHello = {-> println 'hello' }

// Try it out
sayHello()

import static Tools.header should do the trick. You don't need a closure in this case as you call simple method. If you'll have to pass header as a closure somewhere in your code of a.groovy or b.groovy the &header still could be used.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM