rjk*_*lan 9 debugging wolfram-mathematica
在Mathematica中是否有一个设置(我希望它是一个环境变量)会在发生调试错误时使内核退出?通常,我会收到调试错误,笔记本将继续评估错误的数据,迫使我重新启动内核.
Sjo*_*ies 14
遵循从Mathematica工具包借来的想法:
myMessage::debug = "Something went horribly wrong";
Unprotect[Message];
Message[mm : myMessage::debug] :=
Block[{$inMsg = True, result},
Message[mm];
Quit[]] /; ! TrueQ[$inMsg]
Protect[Message];
Run Code Online (Sandbox Code Playgroud)
在这里,替换myMessage::debug
为您要拦截的实际消息类型.
正常消息:
Message[Power::infy]
(* ===>
StringForm::sfr: Item 1 requested in "Infinite expression `1`
encountered. >>" out of range; 0 items available. >>
Power::infy: Infinite expression `1` encountered. >>
*)
Run Code Online (Sandbox Code Playgroud)
你的"调试"消息:
Message[myMessage::debug]
(* ===>
myMessage::debug: Something went horribly wrong
[kernel quits...]
*)
Run Code Online (Sandbox Code Playgroud)
更新
断言消息会获得一些额外的参数,因此您也必须捕获这些参数.顺便说一句,你必须将实际的消息名称放在定义中(不使用我上面使用的示例消息):
Unprotect[Message];
Message[mm : Assert::asrtfl, m___] :=
Block[{$inMsg = True, result},
Message[mm, m];
Quit[]] /; ! TrueQ[$inMsg]
Protect[Message];
Run Code Online (Sandbox Code Playgroud)
此响应假定"调试错误"表示已发出消息.例如,如果尝试除以零,则会将消息作为警告发出:
In[1]:= Print[1/0]
Power::infy: Infinite expression 1/0 encountered. >>
ComplexInfinity
Run Code Online (Sandbox Code Playgroud)
注意即使发出警告消息ComplexInfinity
,Print
语句也打印了如何,表明计算在"错误"之后继续.
我不会重新讨论@ Sjoerd的优秀答案,该答案显示了如何配置Mathematica会话,以便在任何评估发出任何消息时内核将退出.如果您希望更具选择性并且仅在特定评估发出消息时退出内核,则以下函数可能有用:
ClearAll[checkQuit]
SetAttributes[checkQuit, HoldFirst]
checkQuit[expr_, HoldPattern[messages_:Sequence[]]] :=
Check[expr, Message[checkQuit::quit]; Quit[], messages]
checkQuit::quit = "The kernel is being shut down!";
Run Code Online (Sandbox Code Playgroud)
有了这个定义,您可以在特定评估发出任何消息后强制内核退出:
In[37]:= checkQuit[Print[1/0]]
Power::infy: Infinite expression 1/0 encountered. >>
checkQuit::quit: The kernel is being shut down!
Run Code Online (Sandbox Code Playgroud)
如果发出某些消息,如果只是退出内核可能会很方便.为此,checkQuit
接受可选的第二个参数,该参数可用于指定感兴趣的消息:
In[6]:= checkQuit[{}[[10]], Power::infy]
Part::partw: Part 10 of {} does not exist. >>
Out[6]= {}[[10]]
Run Code Online (Sandbox Code Playgroud)
请注意,由于消息不匹配,内核是如何退出的Power::infy
.但考虑一下:
In[7]:= checkQuit[1/0, Power::infy]
Power::infy: Infinite expression 1/0 encountered. >>
checkQuit::quit: The kernel is being shut down!
Run Code Online (Sandbox Code Playgroud)
这里内核退出,因为出现了指示的消息.可以过滤多条消息甚至是预定义的消息组 - 请参阅检查详细信息.
除了其他答案,您可能需要调查使用:
$MessagePrePrint
Run Code Online (Sandbox Code Playgroud)
这允许您在触发任何消息时执行代码.
例如,您可以评估此:
$MessagePrePrint := (Print[Stack[_]]; Dialog[])
Run Code Online (Sandbox Code Playgroud)
它打印正在评估的代码的评估堆栈(有时非常大!).然后,对话框功能将您置于子评估循环中,允许您检查变量的值.要退出对话框循环,您可以评估:
Return[]
Run Code Online (Sandbox Code Playgroud)
它会将您带回主循环(主要评估然后在新消息中完成或中断).
你写了:
首先,我希望笔记本计算机在出现断言错误时停止运行。
您可以通过$AssertFunction
如下定义来做到这一点:
$AssertFunction := Quit[] & ;
Run Code Online (Sandbox Code Playgroud)
现在,当断言失败时,内核退出:
<< ExampleData`FunctionWithAssert`
Compute[ 1.0]
(*=> kernel quits*)
Run Code Online (Sandbox Code Playgroud)
另外,您可以使用Interrupt
相同的方式:
$AssertFunction := Interrupt[] & ;
Run Code Online (Sandbox Code Playgroud)
它允许您中止评估或输入子会话(与Dialog[]
Arnoud的答案相同)。
您还可以扩展此方法以打印失败的断言:
$AssertFunction := (Print[HoldForm @@ #]; Interrupt[]) &;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1145 次 |
最近记录: |