scala - Compiler complains about class that extends DelayedInit not defining delayedInit method -


i have class i'm trying make extend delayedinit:

class foo extends delayedinit {   // expensive initialisation code } 

however when try run sbt compile error:

foo needs abstract, since method delayedinit in trait delayedinit of type (x: => unit)unit not defined 

my understanding extending delayedinit trait initialisation code should automatically wrapped in closure , run in delayedinit method after initialisation complete. i've had stab @ googling , can't seem find example of usage. missing?

how delayedinit works , sample usage

delayedinit trait provides ability control @ point initialisation code within class or object (but not trait) run.

any initialisation code within classes or objects (but not traits) inherited delayedinit passed compiler during initialisation delayedinit method , it's when want run it.

delayedinit method called automatically part of initialisation , running code passed parameter straight away within method still running code during initialisation.

let's start basic scenario:

object main extends delayedinit  {     println ("  initialisation of main object")    override def delayedinit (body: => unit) {      println("delayedinit")      body    }     def main (args: array[string]) {      println("main method")     } } 

will print:

delayedinit   initialisation of main object main method 

in fact, delayedinit method called once every class inherits trait within class hierarchy. more complicated scenario:

abstract class myapplication extends delayedinit {    println ("  initialisation of myapplication class") }  object main extends myapplication  {     println ("  initialisation of main object")    override def delayedinit (body: => unit) {      println("delayedinit")      body    }     def main (args: array[string]) {      println("main method")     } } 

will print:

delayedinit   initialisation of myapplication class delayedinit   initialisation of main object main method 

since main method first method run once initialisation over, want save initialisation code passed delayedinit , run later, within main, since there potentially more 1 bit of code conveniently store in listbuffer (we need keep appending preserve natural execution order). code inside 'main` object this:

private val init = new scala.collection.mutable.listbuffer[()=>unit] override def delayedinit (body: => unit) {   println("delayedinit")   init += (()=>body) // result in nullpointerexception }   def main (args: array[string]) {   println("main method")    (code <- init) code () } 

however, there catch 22: because initialisation of init field delayed along every other initialisation statement there isn't listbuffer[()=>unit] object preserve initialisation code later use!

but, remember?

any initialisation code within classes or objects (but not traits) inherited delayedinit passed compiler during initialisation delayedinit method...

let's re-shuffle things bit, move functionality memorises code later use storedinit trait inherits directly delayedinit:

trait storedinit extends delayedinit {    println ("initialisation of storedinit trait")    private val init = new scala.collection.mutable.listbuffer[()=>unit]    override def delayedinit (body: => unit) {      println("delayedinit")      init += (()=>body)    }       def initialise () {      (code <- init) code ()         } }  // extend storedinit instead of delayedinit abstract class myapplication extends storedinit {    println ("  initialisation of myapplication class") }  object main extends myapplication  {     println ("  initialisation of main object")     def main (args: array[string]) {      println("main method")       initialise() // perform delayed initialisation    } } 

will print:

initialisation of storedinit trait delayedinit delayedinit main method   initialisation of myapplication class   initialisation of main object 

finally, why doesn't delayedinit trait include default implementation of delayedinit method?

to keep compiler hook de-coupled actual implementation of delayed initialisation behaviour. desired behaviour different console application , server-side component has work within specific container.

trait app, however, inherits delayedinit , provides default implementation scala applications.


Comments

Popular posts from this blog

delphi - How to convert bitmaps to video? -

jasper reports - Fixed header in Excel using JasperReports -

python - ('The SQL contains 0 parameter markers, but 50 parameters were supplied', 'HY000') or TypeError: 'tuple' object is not callable -