R – Access values of static closure in Groovy

closuresgroovystatic

I'd like to store some properties in a static closure and later access them during a method call:

class Person {  
static someMap = { key1: "value1", key2: "value2" }  
}

So how can I write a method within Person, which retrieves this stored data?

Best Answer

For the simple case, you're better off using a map.

If you really do want to evaluate it as a closure (possibly to create your own DSL), you'll need to change your syntax slightly as John points out. Here's one way to do it using a Builder class to evaluate the "something" closure within whatever is passed to the builder.

It uses groovy metaprogramming to intercept calls with method/property missing and to save them off:

class SomethingBuilder {
    Map valueMap = [:]

    SomethingBuilder(object) {
        def callable = object.something
        callable.delegate = this
        callable.resolveStrategy = Closure.DELEGATE_FIRST
        callable()
    }

    def propertyMissing(String name) {
        return valueMap[name]
    }

    def propertyMissing(String name, value) {
        valueMap[name] = value
    }

    def methodMissing(String name, args) {
        if (args.size() == 1) {
            valueMap[name] = args[0]
        } else {
            valueMap[name] = args
        }
    }
}

class Person {
    static something = {
        key1 "value1"              // calls methodMissing("key1", ["value1"])
        key2("value2")             // calls methodMissing("key2", ["value2"])
        key3 = "value3"            // calls propertyMissing("key3", "value3")
        key4 "foo", "bar", "baz"   // calls methodMissing("key4", ["foo","bar","baz"])
    }
}

def builder = new SomethingBuilder(new Person())

assert "value1" == builder."key1"  // calls propertyMissing("key1")
assert "value2" == builder."key2"  // calls propertyMissing("key2")
assert "value3" == builder."key3"  // calls propertyMissing("key3")
assert ["foo", "bar", "baz"] == builder."key4"  // calls propertyMissing("key4")