调试scala代码的最佳技术,这些代码会传递lambda主体、匿名类实例和类似的东西



你发现调试scala代码的最佳技术是什么,这些代码传递lambda主体,匿名类实例和类似的东西?

我确信一旦我更好地学习Scala,它将使我更有效率,但是当我试图弄清楚是什么生成了回调(或lambda主体,等等),我在程序执行流程的特定点调用它时,我有时会感到困惑。我尝试了一种技术,你可以在下面看到不起作用…我提供这个代码示例,以便您可以看到我正在尝试完成什么。

def fork[A](a: => Par[A]): Par[A] = {
  val marker  = new java.util.Date().getTime
  log("about to return future with marker: " + marker)
  val func = (es: ExecutorService) => new Future[A] {
    def apply(cb: A => Unit): Unit = {
      log("applying callback (w/ eval) in future apply method: " + this)
      eval(es)(a(es)(cb))
    }
    override def toString : String =  { "execSvc -> future w/marker: " + marker}
  }
  log("returning future creation func: " + func.toString())
  func
}

// a log method that uses a simmple timestamp to help order print statements emitted in multi-threaded programs, 
// and which deliberately slows things down  so we don't see the same time stamp repeated. cheesy, but 
// seems to serve its purpose
def log(msg: String): Unit = {
  println(new java.util.Date().getTime() + " thread: " + Thread.currentThread().getName + " " + msg)
  for (i <- 1 to 100000000) {}          // slow things down !
  System.out.flush()
}

方法'fork'返回一个函数'F',该函数接受一个executor服务参数,并最终向executor服务提交一个Future实例。在fork方法中,我会发出一个标记,告诉我"我在这里创建了函数F的实例!"',然后在我调用函数之前(在'fork'之外的某个地方)通过传递一个执行器服务立场,我想打印函数对象实例并看到标记,这样我就可以跟踪到F被创建的地方(即…在'fork'的某些调用中)。当前的解决方案给出了以下输出:

1438983547813 thread: pool-1-thread-1 returning future creation func: <function1>

我不想看到通用的'function1'标签..我想看到结果我的重写toString方法,它将打印我的标记。

谁有什么很酷的技巧来做到这一点?一般来说,如果有博客文章或文章讨论类似的调试技巧,如果有人能提供一些链接,我将不胜感激。谢谢!

(来源:如果你对上面的代码很好奇,它来自github网站与这本书:Scala的函数式编程。它是"Nonblocking"类的一部分。

快乐时光来了。这篇文章给了我答案。下面的代码显示了我如何将它应用到我的情况。

    def fork[A](a: => Par[A]): Par[A] = {
      val marker = new java.util.Date().getTime
      log("about to return future with marker: " + marker)
      System.out.flush()
      val func = new Function1[ExecutorService, Future[A]] {
        def apply(es: ExecutorService) = {
          new Future[A] {
            def apply(cb: A => Unit): Unit = {
              log("applying callback (w/ eval) in future apply method: " + this)
              eval(es)(a(es)(cb))
            }
            override def toString: String = {
              "I am a future object constructed from marker: " + marker
            }
          }
        }
        override def toString: String = {
          "I am a method that takes an exec svc and returns a futture  i was constructed from marker: " + marker
        }
      }
      log("returning future creation func: " + func)
      func
    }

我的输出现在包括标记,我发现这非常有助于追溯到我实例化的函数块,我在某个点调用:

        1438988219429 thread: main applying callback (w/ eval) in future apply method: I am a future object constructed from marker: 1438988219269
        1438988219460 thread: main in eval now / creating callable with marker: 1438988219460
        1438988219491 thread: main submitting callable:fpinscala.parallelism.Nonblocking$Par$$anon$6@3fb6a447
        1438988219526 thread: pool-1-thread-1 executing callable with 1438988219460
        1438988219561 thread: pool-1-thread-1 about to return future with marker: 1438988219561
        1438988219598 thread: pool-1-thread-1 returning future creation func: I am a method that takes an exec svc and returns a futture  i was constructed from marker: 1438988219561
        1438988219651 thread: pool-1-thread-1 applying callback (w/ eval) in future apply method: I am a future object constructed from marker: 1438988219561
        1438988219686 thread: pool-1-thread-1 in eval now / creating callable with marker: 1438988219686

最新更新