33

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.

Dónal
  • 185,044
  • 174
  • 569
  • 824

2 Answers2

33

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"
Dónal
  • 185,044
  • 174
  • 569
  • 824
John Wagenleitner
  • 10,967
  • 1
  • 40
  • 39
17

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.

albciff
  • 18,112
  • 4
  • 64
  • 89