I have a class that extends Expando and gets injected with dynamic properties.
class Dynamo extends Expando {
}
Dynamo dynamic = [ firstName: 'bob', lastName: 'dobbs' ]
I'd like to create a dynamic property fullName that evaluates to "$lastName, $firstName".
While it sort of does work to do this:
dynamic.fullName = { "$lastName, $fullName" }
It requires an call() or implicit call with () to return the string, otherwise it just gives the closure toString()
assert dynamic.fullName() == 'dobbs, bob'
Passes
But
assert dynamic.fullName == 'dobbs, bob'
Fails because that evaluates to the toString of the closure
I can always do this
Dynamo dynamic = [ firstName: 'bob', lastName: 'dobbs', fullName: 'dobbs, bob' ]
But that ain't DRY...
For parameterless methods, Groovy needs parenthesis. I can think of two solutions:
Solution 1: Metaclass the getter getFullName
:
Dynamo dynamo = [ firstName: 'bob', lastName: 'dobbs' ]
dynamo.metaClass.getFullName = { "$lastName, $firstName" }
assert dynamo.fullName == 'dobbs, bob'
Solution 2: Hook into the property getters with getProperty
:
Dynamo dyn2 = [ firstName: 'john', lastName: 'doe' ]
dyn2.metaClass.getProperty = { String property ->
if (property == "fullName") {
"${delegate.lastName}, ${delegate.firstName}"
}
}
assert dyn2.fullName == 'doe, john'