Search code examples
scalascala-2.9

how to allow passing in a => AnyRef function and call that function


I have the following code

class LazyLogRecord(
  level: javalog.Level,
  messageGenerator: => AnyRef
     ) extends LogRecord(level, "") {

  // for each logged line, generate this string only once, regardless of how many handlers  there are:
  override lazy val getMessage : String = messageGenerator().toString
}

This code does not compile because I try to invoke messageGenerator. I can modify the code from

messageGenerator: => AnyRef
to
messageGenerator: () => AnyRef

but then my upstream code log.debug("hi there"+variable+"asfdsaf") does not compile unless I change that code to log.debug( () => {"hi there"+variable+"asdfas"} )

If I just stick with messageGenerator.toString, the getMessage is returning "function0" instead of the invoked function results with toString called on that result.

How can I fix this to have the best of both worlds?

EDIT: Very odd, I just modified the code to this

override lazy val getMessage : String = {
   val funkyThing : () => AnyRef = messageGenerator
   funkyThing().toString
}

and it says mesasgeGenerator is type "AnyRef" when it should say type "=> AnyRef". It then complains it can't convery "AnyRef" to "() => AnyRef"

what is going on there? That isn't right either.

EDIT 2: I am beginning to think it is a client problem. My client code may be wrong. My client code was like this where I pass in a function that is passed down to LazyLogRecord....is my definition of function wrong? I think it is as then I pass it to => AnyRef and it's not exactly that same type but I needed to test the lazy evaluation out and it failed.

  val logger = Logger.get("lazyTest2")
  logger.setLevel(Level.DEBUG)
  var executed = false
  val function = () => {
    executed = true
    "asdf"+executed+" hi there"
  }


  logger.debugLazy(function)
  assert(!executed)

thanks, Dean


Solution

  • Based on your latest update, changing your call to:

    val logger = Logger.get("lazyTest2")
    logger.setLevel(Level.DEBUG)
    var executed = false
    
    
    logger.debugLazy({
      executed = true
      "asdf"+executed+" hi there"
    })
    

    Should fix your issue. Your previous code is being interpreted as:

    logger.debugLazy({function})
    

    which is a function that returns your function0 as it's result which is not what you wanted. You could also try defining function as a def instead of a val like so:

    def function() = {
      executed = true
      "asdf"+executed+" hi there"
    } 
    logger.debugLazy(function)
    

    and that should work as well.