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

Chr*_*ong 3 elm

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

import Debug exposing (log)

f x =
    let _ = log "Hello, world!" ()
    in f x
Run Code Online (Sandbox Code Playgroud)

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

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

Chr*_*ong 6

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

问题

我参与了Elm REPL的实施.相关功能在这里:Eval.Code.run

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

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

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

Utils.CommandFailed结果有益包括标准输出(其被绑定到_out),但是这代码忽略它,只是引发错误.

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

解决方法

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

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

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