In the Groovy code below I replace the values of the feck
, arse
, drink
properties of an instance of Foo
with those of an instance of Foo2
class Foo { def feck = "fe" def arse = "ar" def drink = "dr" } class Foo2 { def feck = "fe2" def arse = "ar2" def drink = "dr2" } def f = new Foo() def f2 = new Foo2() ["feck", "arse", "drink"].each {it -> f."$it" = f2."$it" }
Is there a better way to do this? My specific concern with the code above is that the property names are stored as strings in a list, which would likely be missed when (for example) using a refactoring IDE to change one of these property names.
We can iterate through entries using the each() and eachWithIndex() methods. The each() method provides implicit parameters, like entry, key, and value, which correspond to the current Entry.
When a Groovy class definition declares a field without an access modifier, then a public setter/getter method pair and a private instance variable field is generated which is also known as "property" according to the JavaBeans specification.
The if's condition needs to be an expression. Assertions are for cases where you want it to fail loudly if what you're asserting is not true. Don't use assert unless you want it to throw an exception if the condition is not met.
I haven't yet found a good approach for excluding the read-only properties (i.e., metaClass, class), but if you want to set the value of all properties in the Foo instance that are also in the Foo2 instance you could do the following.
class Foo { def feck = "fe" def arse = "ar" def drink = "dr" } class Foo2 { def feck = "fe2" def arse = "ar2" def drink = "dr2" } def f = new Foo() def f2 = new Foo2() f2.properties.each { prop, val -> if(prop in ["metaClass","class"]) return if(f.hasProperty(prop)) f[prop] = val } assert f.feck == "fe2" assert f.arse == "ar2" assert f.drink == "dr2"
Very late answer... however what about to take only the non synthetic declaredFields
of Foo
class. Using your approach:
class Foo { def feck = "fe" def arse = "ar" def drink = "dr" } class Foo2 { def feck = "fe2" def arse = "ar2" def drink = "dr2" } def f = new Foo() def f2 = new Foo2() Foo.declaredFields.findAll { !it.synthetic }*.name.each {it -> f[it] = f2[it] } assert f.feck == "fe2" assert f.arse == "ar2" assert f.drink == "dr2"
If in refactoring something change for example in Foo
but not in Foo2
then an Exception
will be thrown from this code advising that something is wrong.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With