#2148 FieldNotSetErr when ctor chaining

SlimerDude Tue 21 May 2013

Me again!

When I chain my ctor like this:

class CtorChain {
  const Str poo
  
  new make(|This|? in := null) {
    in?.call(this)
  }

  new makeFromPoo(Str poo, |This|? in := null) : this.make(in) {
    this.poo = poo
  }  

  static Void main(Str[] args) {
    CtorChain("Poo").toStr
  }
}

I get a FieldNotSetErr when leaving the inner ctor:

sys::FieldNotSetErr: Wotever::CtorChain.poo
  Wotever::CtorChain.checkFields$CtorChain (CtorChain.fan:2)
  Wotever::CtorChain.make$ (CtorBug.fan:5)
  Wotever::CtorChain.makeFromPoo$ (CtorBug.fan:9)
  Wotever::CtorChain.makeFromPoo$ (CtorBug.fan)
  Wotever::CtorChain.makeFromPoo (CtorBug.fan:9)
  Wotever::CtorChain.main (CtorBug.fan:14)

But because I'm still in the 1st outer ctor make(Str, |This|), I'd expect all checks to be held off until I leave that ctor.

brian Tue 21 May 2013

The problem every constructor has to stand on its own. So one make completes it will check that all non-nullable fields were set before exiting. I'm sure we could try and do something crazy like know make was being called in context of another constructor, but that would start to get pretty crazy complicated.

SlimerDude Tue 21 May 2013

Yeah, nesting calls can get pretty complicated. There's a lot (well, shed load!) of nesting inside afIoc. To simplify matters there I pass around a Ctx object which holds various stacks of contextual info. I push contextual info onto the stacks when I go deeper, and pop them on my return.

If you ever re-visit the ctor code, you could maybe think about doing similar there.

Login or Signup to reply.