#2579 It-Block Constructor Chaining

go4 Thu 24 Nov 2016

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")
  }
}

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:

  1. You call Sub.make2()
  2. Base is created
  3. Default values for fields in Base are set. (Which in your example, there aren't any)
  4. The Base ctor is called, which sets a and b
  5. Sub is created
  6. Default values for fields in Sub are set. ( Note field b is now overridden with the default value of -1 )
  7. 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

go4 Fri 25 Nov 2016

Thank you, it's good idea to set the default values in ctor.

Login or Signup to reply.