Using const for "data classes", I'm repeating this code to update the data.
const class Person
{
Int id
Str name
new make(|This| f)
{
f(this)
// put default value if absent
}
new makeCopy(Person that, |This| f)
{
this.id = that.id
this.name = that.name
f(this)
}
This copy(|This| f)
{
makeCopy(this, f)
}
}
// Usage
p1 := Person { id = 3; name = "foo" }
p2 := p.copy { name = "bar" }
Do you use something similar? Something better? How do you do it?
SlimerDudeWed 23 Nov 2016
Hi Fraya,
Another good question!
Fantom only allows the one it-block in a ctor parameter list so in the past I've used a field map and reflection to do something like this:
const class Person {
const Int id
const Str name
new make(|This| f) { f(this) }
Person clone([Field:Obj?]? newVals := null) {
fieldVals := Field:Obj?[:]
this.typeof.fields.each {
fieldVals[it] = it.get(this)
}
if (newVals != null)
fieldVals.setAll(newVals)
planFunc := Field.makeSetFunc(fieldVals)
return Person(planFunc)
}
}
And use it like this:
p1 := Person { // create
it.id = 3
it.name = "foo"
}
p2 := p1.clone // clone p1
p3 := p2.clone([ // clone p2 & set new name
Person#name : "Bob"
])
You can't pass in a normal func to set the fields as you run into const issues.
brianWed 23 Nov 2016
I personally like a constructor that takes an original instance to copy from and an it-block to tweak individual fields:
class Foo
{
new make(Foo? orig := null, |This|? f := null)
{
if (orig != null)
{
this.a = orig.a
this.b = orig.b
}
if (f != null) f(this)
}
const Str a := "xxx"
const Str b := "yyy"
}
x := Foo(null) { it.a = "1" }
y := Foo(x) { it.a = "2" }
frayaWed 23 Nov 2016
@SlimerDude
Thank you for your response, your solution can be a mixin returning This and changing the function last line to
fraya Wed 23 Nov 2016
Using const for "data classes", I'm repeating this code to update the data.
Do you use something similar? Something better? How do you do it?
SlimerDude Wed 23 Nov 2016
Hi Fraya,
Another good question!
Fantom only allows the one
it-block
in a ctor parameter list so in the past I've used a field map and reflection to do something like this:And use it like this:
You can't pass in a normal func to set the fields as you run into
const
issues.brian Wed 23 Nov 2016
I personally like a constructor that takes an original instance to copy from and an it-block to tweak individual fields:
fraya Wed 23 Nov 2016
@SlimerDude
Thank you for your response, your solution can be a mixin returning
This
and changing the function last line to? Can I haz a Cloneable?? :)
@andy thank you, i'll test it