How to call super constructor, when the super class has a it-block constructor. Thanks.
new make(|This| f) : super.make(null) { f(this) } //throw FieldNotSetErr
new make2(|This| f) : super.make(f) {} //Sub class is not inited correctly
Test code:
const class Val {
const Int v
new make(Int val) { v = val }
override Str toStr() { v.toStr }
}
class Base {
Val a
new make(|This|? f := null) {
f?.call(this)
}
}
class Sub : Base {
Val b := Val(-1)
new make(|This| f) : super.make(null) {
f(this)
}
new make2(|This| f) : super.make(f) {
}
}
class Main {
static Void main() {
//echo("Hello World")
x := Sub.make2 {
a = Val(1)
b = Val(2)
echo("init")
}
echo("$x.a, $x.b")
}
}
SlimerDudeThu 24 Nov 2016
Hi Go4, that's a good tricky question!
Using new make(|This| f) : super.make(f) {} is the way to chain it-block ctors, only it doesn't work in your example!
Here's the sequence of events that explains why it doesn't work:
You call Sub.make2()
Base is created
Default values for fields in Base are set. (Which in your example, there aren't any)
The Base ctor is called, which sets a and b
Sub is created
Default values for fields in Sub are set. ( Note field b is now overridden with the default value of -1 )
The Sub ctor is called
As noted, this is not very ideal; perhaps Brian can ticket a better way to initialise classes / ctors?
Following is a workaround, essentially you move setting the default values to the ctor, checking first if it's been set.
class Base {
Str a
new make(|This| f) { f(this) }
}
class Sub : Base {
Str b
new make(|This| f) : super.make(f) {
// thankfully this still compiles in the ctor despite b not being nullable
if (b == null)
b = "-1"
}
}
...
x1 := Sub { it.a = "1" }
echo("$x1.a, $x1.b") // --> 1, -1
x2 := Sub {
it.a = "1"
it.b = "2"
}
echo("$x2.a, $x2.b") // --> 1, 2
go4Fri 25 Nov 2016
Thank you, it's good idea to set the default values in ctor.
go4 Thu 24 Nov 2016
How to call super constructor, when the super class has a it-block constructor. Thanks.
Test code:
SlimerDude Thu 24 Nov 2016
Hi Go4, that's a good tricky question!
Using
new make(|This| f) : super.make(f) {}
is the way to chain it-block ctors, only it doesn't work in your example!Here's the sequence of events that explains why it doesn't work:
Sub.make2()
Base
is createdBase
are set. (Which in your example, there aren't any)Base
ctor is called, which setsa
andb
Sub
is createdSub
are set. ( Note fieldb
is now overridden with the default value of-1
)Sub
ctor is calledAs noted, this is not very ideal; perhaps Brian can ticket a better way to initialise classes / ctors?
Following is a workaround, essentially you move setting the default values to the ctor, checking first if it's been set.
go4 Fri 25 Nov 2016
Thank you, it's good idea to set the default values in ctor.