Доступ к значениям статического замыкания в Groovy - PullRequest
3 голосов
/ 24 января 2010

Я хотел бы хранить некоторые свойства в статическом замыкании и позже обращаться к ним во время вызова метода:

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

Так, как я могу написать метод в Person, который извлекает эти сохраненные данные?

Ответы [ 3 ]

7 голосов
/ 24 января 2010

Для простого случая лучше использовать карту.

Если вы действительно хотите оценивать это как замыкание (возможно, для создания собственного DSL), вам нужно немного изменить синтаксис, как указывает Джон. Вот один из способов сделать это с помощью класса Builder, чтобы оценить замыкание «что-то» внутри того, что передается построителю.

Использует мета-программирование на языке groovy для перехвата вызовов с отсутствующим методом / свойством и их сохранения:

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")
6 голосов
/ 24 января 2010

Если их нужно инициализировать замыканием, а не картой, тогда кто-то должен запустить замыкание, чтобы подобрать и записать значения, как они установлены.

Ваш синтаксис отсутствуетне действительно.Помните, что замыкания - это просто анонимные методы.Ваш синтаксис выглядит так, как будто вы пытаетесь определить карту, но замыкания должны вызывать методы, устанавливать переменные или возвращать карты.например,

static someClosure = { key1 = "value1"; key2 = "value2" } // set variables
static someClosure = { key1 "value1"; key2 = "value2" } // call methods
static someClosure = { [key1: "value1", key2: "value2"] } // return a map

Тогда, конечно, кто бы ни выполнял замыкание, он должен иметь правильное метапрограммирование для записи результатов.

Похоже, что вы действительно хотите просто определить карту.*

static someMap = [key1: "value1", key2: "value2"]
0 голосов
/ 06 марта 2011

Вот что я придумал для извлечения статических свойств замыкания:

class ClosureProps {

       Map props = [:]  
       ClosureProps(Closure c) {  
           c.delegate = this  
           c.each{"$it"()}  
       }  
       def methodMissing(String name, args) {  
           props[name] = args.collect{it}  
       }  
       def propertyMissing(String name) {  
           name  
       }  
}  

// Example  
class Team {

        static schema = {  
            table team  
            id teamID  
            roster column:playerID, cascade:[update,delete]  
        }  
}  
def c = new ClosureProps(Team.schema)  
println c.props.table  
...