0

I wish to pass the value of var/val from one method to another.
eg, I have

object abc {

  def onStart = {    
    val startTime = new java.sql.Timestamp( new Date())
  }

  def onEnd = {
    //use startTime here 
  }
}

calling:

onStart()  
executeReports(reportName, sqlContexts)  
onEnd()  

Here onStart() and onEnd() are job monitoring functions for executeReports().
executeReports() runs in a loop for 5 reports.

I have tried using global variables like

object abc{

  var startTime : java.sql.Timestamp = _

  def onStart = {    
    startTime = new java.sql.Timestamp( new Date())
  }

  def onEnd = {
    //use startTime here 
  }

}

but the catch with this is when the loop executes for the next report, the startTime does not change.

I also tried using Singleton Class that did not work for me either.

My requirement is to have a startTime for every iteration i.e, for every report. Any ideas are welcome here. I'll be happy to provide more clarification on my requirement if needed.

0

3 Answers 3

5

The common Scala solution to this is to write a function that wraps other functions and performs the setup and shutdown internally.

def timeit[T]( fun: => T ): T = {
  val start = System.currentTimeMillis //Do your start stuff
  val res = fun
  println (s"Time ${System.currentTimeMillis - start}") // Do your end stuff
  res
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks RussS ! In my case I'm tied to the design and I cannot make any changes.. I loved your answer though. :) its neat and efficient as well
1

RussS has the better solution, but if for some reason you're wedded to the design you've described, you might try using a mutable val, i.e. a mutable collection.

I got this to compile and pass some small tests.

object abc {
  private val q = collection.mutable.Queue[java.sql.Timestamp]()

  def onStart = {
    q.enqueue(new java.sql.Timestamp(java.util.Calendar.getInstance().getTime.getTime))
  }

  def onEnd = {
    val startTime = q.dequeue
  }
}

Comments

0

Base from your requirements, it might be better to do it this way.

case class Job(report: List<Report>) {
 def execute // does the looping on Report by calling start and call end to generate monitoring data

 private def start // iterate over each Report and calls it's execute method

 private def end // iterate over each Report and uses startTime and executionTime to generate monitoring data. 
}

abstract class Report {
 var startTime: DateTime //Time started for the report
 def doReport // unimplemented method that does the report generation. 
 def execute // first set stateTime to Now then call doReport, lastly calculate executionTime
}

The subtype of the Report should implement the doReport which does actual reporting.

You can also change the Job.execute method to accept

report: List<Report>

so that you can have a singleton Job (For sure, start and end will be the same for all Job you have.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.