你发现调试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