2

我正在开发一个 Groovy 库,通过简单的语法和丰富的事件处理程序提供变量绑定/同步。首先,我的目标是归档运行以下内容:

def a = 1 
def b = 1
def c = 1
a bind { b + c }
assert a==2 & b==1 & c==1
b = 3
assert a==4 & b==3 & c==1
c = -1
assert a==2 & b==3 & c==-1

我想避免提供额外类的 Java FX 方法,而是使用此功能增强对象。

我一直在寻找一些物体的跟踪。Groovy 没有赋值表达式的重载。目前,我看到了重 AST 转换的解决方案(也许 dsld 可能会有所帮助)。

也许我错过了一些对象跟踪、事件或其他什么?

4

1 回答 1

1

我假设您正在使用脚本编写代码。用以下想法做了你想做的事:

  • 与其使用 将值绑定到键Script.binding,不如创建一个Variable同时代表value和变量的类name
  • 对象上调用的每个方法Variable都被委托给它的值;
  • Listener封装了对更新操作的引用和需要更新的对象的类Variable
  • 一个updateListeners()更新监听器的方法;
  • 一种bind(closure)只是绕过对变量对象的闭包的方法。它几乎可以被删除并写成a { b + c };

    class Listener { Closure operation; Variable variable }
    
    class Variable implements GroovyInterceptable { 
        String name; def value
    
        def invokeMethod(String method, args) {
            def var = args[0]
            var.class == Variable ? 
                    value."$method"(var.value) : value."$method"(var)
        }
    }
    
    Variable.metaClass.call = { Closure operation ->
        binding['listeners'] << 
                new Listener(operation: operation, variable: delegate)
        updateListeners()
    }
    
    def bind(Closure operation) { operation }
    
    def updateListeners() {
        binding.listeners.each {
            it.variable.value = it.operation()
        }
    }
    
    void setProperty(String prop, value) { 
        if (!binding.hasVariable('listeners')) binding['listeners'] = []
        binding[prop] = new Variable(name: prop, value: value)
        updateListeners()
    }
    

你的测试就像一个魅力。

于 2013-04-01T01:27:06.853 回答