#2592 It block chaining with const abstract base class

fraya Thu 26 Jan

I have a problem similar to http://fantom.org/forum/topic/2579 but after read it and test it, I can't solve my problem. Please help me to find the error.

const abstract class Generation
{
  const Int genes
  const Int size
  const Float rate

  name make(|This| f)
  {
    f(this)
    if (genes == null || genes < 1)
      throw ArgErr("...")
    if (size == null || size < 1)
      throw ArgErr("...")
    if (rate == null)
      rate = 0.0f
  }

  abstract Obj makeRndGen(Float probability)

  ... more methods
}

const class BitGeneration : Generation
{
  new make(|This| f) : super.make(f)
  {
    if (rate == null)
      rate = 0.5f
  }

  override Obj makeRndGen(Float probability)
  {
    probability < rate ? true : false
  }
}

fansh> b := BitGeneration { genes=3; size=2 }
sys::Err: java.lang.VerifyError: (class: fan/ga/Generation, method: make$   
signature: (Lfan/ga/Generation;Lfan/sys/Func;)V) Expecting to find object/array 
on stack

I have tried to initialize all the values in Generation constructor and in BitGeneration constructor but I don't find the solution.

Can you help me? Thanks.

SlimerDude Fri 27 Jan

This looks to be a Fantom bug to me. Here's a simplified example:

class SuperClass {
  const Int field

  new make(|This|? f) {
    f?.call(this)
    if (field == null)
      field = 9
  }
}

class SubClass : SuperClass {
  new make(|This|? f) : super(f) { }
}

Which gives:

sys::Err: java.lang.VerifyError: (class: fan/afFantomLang/SuperClass, method: make$ signature: (Lfan/afFantomLang/SuperClass;Lfan/sys/Func;)V) Expecting to find object/array on stack
  afExample::Example.main (Example.fan:19)
  java.lang.reflect.Method.invoke (Method.java:597)
  ...

The error is cause by the null check:

if (field == null)

A work around for now is to make the fields nullable:

const abstract class Generation {
  const Int? genes
  const Int? size
  const Float? rate

  ...
}

Login or Signup to reply.