underwood
underwood

Reputation: 933

Pass values between 2 methods of same Object in Scala

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.

Upvotes: 0

Views: 268

Answers (3)

Leo Bufi Barrameda
Leo Bufi Barrameda

Reputation: 359

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.)

Upvotes: 0

jwvh
jwvh

Reputation: 51271

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
  }
}

Upvotes: 1

RussS
RussS

Reputation: 16576

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
}

Upvotes: 5

Related Questions