f) -- (1) readTex-6ren">
gpt4 book ai didi

debugging - 如何使用 PureScript 进行调试?

转载 作者:行者123 更新时间:2023-12-04 14:44:30 25 4
gpt4 key购买 nike

问题
以下是一个最小的、人为的示例:

read :: FilePath -> Aff String
read f = do
log ("File: " <> f) -- (1)
readTextFile UTF8 f -- (2)
我想做一些调试登录 (1) , 在 (2) 上的潜在错误之前发生。到目前为止,在 Spago REPL 中执行以下代码适用于成功案例:
$ spago repl
> launchAff_ $ read "test/data/tree/root.txt"
File: test/data/tree/root.txt
unit
问题:如果 (2) 出现错误- 文件是这里的目录 - , (1)似乎根本没有执行:
$ spago repl
> launchAff_ $ read "test/data/tree"
~/purescript-book/exercises/chapter9/.psci_modules/node_modules/Effect.Aff/foreign.js:532
throw util.fromLeft(step);
^

[Error: EISDIR: illegal operation on a directory, read] {
errno: -21,
code: 'EISDIR',
syscall: 'read'
}
原始问题更复杂,包括多层递归(请参阅 E-Book exercise 3 ),我需要记录日志以调试上述错误。
问题
  • 无论这里即将发生的错误,我如何正确记录?
  • (可选)是否有更复杂、完善的调试替代方案 - purescript-debugger ?一个专门的 VS Code 调试扩展/功能将是蛋糕上的樱桃。
  • 最佳答案

    首先,您观察到的症状并不意味着第一行不​​执行。它确实总是执行,由于控制台在 PureScript REPL 中的工作方式,您只是看不到它的输出。输出被吞了。遗憾的是,这不是 REPL 的唯一问题。
    您可以通过替换 log 来验证第一行总是被执行与 throwError并观察到错误总是被抛出。或者,您可以让第一行修改可变单元格而不是写入控制台,然后检查单元格的内容。
    最后,这只发生在 REPL 中。如果你把那个 launchAff_内部电话main并运行该程序,您将始终获得控制台输出。

    现在到手头的实际问题:如何调试跟踪。
    如果你负担得起,登录到控制台是没问题的,但有一种更优雅的方式: Debug.Trace.trace .
    这个函数有一个隐藏的效果——即它的类型说它是纯的,但它在调用时确实产生了效果。这个小谎言让你用trace在纯设置中,从而调试纯代码。不需要 Effect !只要仅用于调试就可以,但不要将其放入生产代码中。
    它的工作方式是它需要两个参数:第一个被打印到控制台,第二个是打印后要调用的函数,整个过程的结果是该函数返回的任何内容。例如:

    calculateSomething :: Int -> Int -> Int
    calculateSomething x y =
    trace ("x = " <> show x) \_ ->
    x + y

    main :: Effect Unit
    main =
    log $ show $ calculateSomething 37 5

    > npx spago run
    'x = 37'
    42
    第一个参数可以是任何东西,而不仅仅是字符串。这使您可以轻松打印大量内容:
    calculateSomething :: Int -> Int -> Int
    calculateSomething x y =
    trace { x, y } \_ ->
    x + y

    > npx spago run
    { x: 37, y: 5 }
    42
    或者,将其应用于您的代码:
    read :: FilePath -> Aff String
    read f = trace ("File: " <> f) \_ -> do
    readTextFile UTF8 f
    但这里有一个微妙的细节:只要您调用 read,就会发生这种跟踪。 ,即使结果 Aff永远不会被实际执行。如果您需要在有效执行时进行跟踪,则需要创建 trace调用部分 Action ,注意不要让它成为序列中的第一个 Action :
    read :: FilePath -> Aff String
    read f = do
    pure unit
    trace ("File: " <> f) \_ -> pure unit
    readTextFile UTF8 f
    当然,每次需要在有效上下文中进行跟踪时都这样做有点不方便,因此有一个特殊的函数可以为您执行此操作 - 它称为 traceM :
    read :: FilePath -> Aff String
    read f = do
    traceM ("File: " <> f)
    readTextFile UTF8 f
    如果你看看它的 source code ,您会看到它与我在上面的示例中所做的完全一样。

    可悲的是, trace发生异常时不会在 REPL 中为您提供帮助,因为它仍在打印到控制台,因此由于相同的原因它仍然会被吞下。
    但是即使没有被吞下,输出也会有点乱码,因为 trace实际上以颜色输出(帮助您在其他输出中区分),而 PureScript REPL 与颜色有复杂的关系:
    > calculateSomething 37 5
    ←[32m'x = 37'←[39m
    42

    关于debugging - 如何使用 PureScript 进行调试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65492308/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com