将Groovy闭包注入充当属性的Expando

将Groovy闭包注入充当属性的Expando,groovy,closures,expando,Groovy,Closures,Expando,我有一个扩展Expando并注入动态属性的类 class Dynamo extends Expando { } Dynamo dynamic = [ firstName: 'bob', lastName: 'dobbs' ] 我想创建一个计算结果为“$lastName,$firstName”的动态属性fullName 虽然这样做是可行的: dynamic.fullName = { "$lastName, $fullName" } 它需要一个call()或带()的隐式调用来返回字符串,否则它

我有一个扩展Expando并注入动态属性的类

class Dynamo extends Expando {
}

Dynamo dynamic = [ firstName: 'bob', lastName: 'dobbs' ]
我想创建一个计算结果为“$lastName,$firstName”的动态属性fullName

虽然这样做是可行的:

dynamic.fullName = { "$lastName, $fullName" }
它需要一个call()或带()的隐式调用来返回字符串,否则它只给出toString()的闭包

通过

但是

失败,因为它的计算结果是闭包的toString

我总能做到这一点

Dynamo dynamic = [ firstName: 'bob', lastName: 'dobbs', fullName: 'dobbs, bob' ]

但这并不是干的…

对于无参数方法,Groovy需要括号。我可以想出两种解决办法:

解决方案1:元类getter
getFullName

Dynamo dynamo = [ firstName: 'bob', lastName: 'dobbs' ]

dynamo.metaClass.getFullName = { "$lastName, $firstName" }

assert dynamo.fullName == 'dobbs, bob'

解决方案2:使用
getProperty
钩住属性getter:

Dynamo dyn2 = [ firstName: 'john', lastName: 'doe' ]
dyn2.metaClass.getProperty = { String property ->
    if (property == "fullName") { 
        "${delegate.lastName}, ${delegate.firstName}" 
    } 
}

assert dyn2.fullName == 'doe, john'

对于无参数方法,Groovy需要括号。我可以想出两种解决办法:

解决方案1:元类getter
getFullName

Dynamo dynamo = [ firstName: 'bob', lastName: 'dobbs' ]

dynamo.metaClass.getFullName = { "$lastName, $firstName" }

assert dynamo.fullName == 'dobbs, bob'

解决方案2:使用
getProperty
钩住属性getter:

Dynamo dyn2 = [ firstName: 'john', lastName: 'doe' ]
dyn2.metaClass.getProperty = { String property ->
    if (property == "fullName") { 
        "${delegate.lastName}, ${delegate.firstName}" 
    } 
}

assert dyn2.fullName == 'doe, john'

我想当另一台发电机有一个“全名”定义了一个真实属性时,我会遇到一个元分类问题
Dynamo dyn3=[fullName:'Anonymous']
但是Expando在元类getFullName之前解析映射属性,所以一切都很好->仍然想知道是否有办法通过一个可能只是另一个属性的惰性eval GString来做到这一点,但这可能很好,我想当另一台发电机有一个“全名”定义了一个真正的属性时,我会遇到元分类的问题
Dynamo dyn3=[fullName:'Anonymous']
但是Expando在元类getFullName之前解析映射属性,所以一切都很好->仍然想知道是否有办法使用一个可能只是另一个属性的惰性eval GString来实现这一点,但这可能很好。