为什么我不能在Elm REPL的无限循环中从Debug.log获得输出?

时间:2017-01-24 20:48:24

标签: elm

我使用无限循环调试某些代码,但这很困难,因为我无法获取任何日志消息。这是一个简化的案例:

import Debug exposing (log)

f x =
    let _ = log "Hello, world!" ()
    in f x

如果我在f ()这样的Elm REPL中运行它,它会无限循环并且永远不会像我期望的那样打印出"Hello, world!"

我查看了Debug.log的实现(跟随Native.Debug.log),但似乎只是同步调用process.stdout.writeconsole.log,所以我'我很惊讶我没有看到任何输出。

1 个答案:

答案 0 :(得分:6)

这只是Elm REPL中的一个错误。

问题

我参与了Elm REPL的实施。相关功能在此处:Eval.Code.run

这个run函数似乎是执行一段代码的函数。看起来每行代码都是通过Elm.Utils在子进程中执行的。 unwrappedRun。运行它的方式有两个问题:

  • 子流程的stdout没有流式传输;它只在整个子流程完成后才返回。因此,只要您等待代码完成评估,您就不会看到任何内容。
  • 如果你点击ctrl-c过早地结束评估(工作正常,然后返回到Elm提示符),Elm Repl会忽略返回给它的标准输出。请注意pattern match for CommandFailed

Left (Utils.CommandFailed _out err) -> throwError err

Utils.CommandFailed结果有助于包含stdout(绑定到_out),但是此代码忽略它并且只是抛出错误。

所以基本上这不是Elm编译器或运行时奇怪的事情,只是REPL不如记录结果那么好。

解决方法

作为一种解决方法,为了调试诸如无限循环之类的东西,你可以

  1. 将一些测试代码放在新文件Scratch.elm中,例如x = f ()
  2. 使用elm-make Scratch.elm --output scratch.js
  3. 编译代码
  4. 使用node scratch.js
  5. 运行代码

    然后输出将流式传输到您的终端。