在Mathematica中是否有一个设置(我希望它是一个环境变量)会导致内核在发生调试错误时退出?通常,我会收到调试错误,笔记本将继续评估错误的数据,迫使我重新启动内核。
答案 0 :(得分:14)
遵循从Mathematica toolbag借来的想法:
myMessage::debug = "Something went horribly wrong";
Unprotect[Message];
Message[mm : myMessage::debug] :=
Block[{$inMsg = True, result},
Message[mm];
Quit[]] /; ! TrueQ[$inMsg]
Protect[Message];
在此处,将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. >>
*)
您的“调试”消息:
Message[myMessage::debug]
(* ===>
myMessage::debug: Something went horribly wrong
[kernel quits...]
*)
更新
断言消息会获得一些额外的参数,所以你也必须抓住它们。顺便说一下,你必须将实际的消息名称放在定义中(不使用我上面使用的示例消息):
Unprotect[Message];
Message[mm : Assert::asrtfl, m___] :=
Block[{$inMsg = True, result},
Message[mm, m];
Quit[]] /; ! TrueQ[$inMsg]
Protect[Message];
答案 1 :(得分:8)
此响应假设“调试错误”表示已发出Message。例如,如果尝试除以零,则会将消息作为警告发出:
In[1]:= Print[1/0]
Power::infy: Infinite expression 1/0 encountered. >>
ComplexInfinity
注意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!";
有了这个定义,你可以在特定评估发出任何消息后强制内核退出:
In[37]:= checkQuit[Print[1/0]]
Power::infy: Infinite expression 1/0 encountered. >>
checkQuit::quit: The kernel is being shut down!
如果发出某些消息,如果只是退出内核可能会很方便。为此,checkQuit
接受可选的第二个参数,该参数可用于指定感兴趣的消息:
In[6]:= checkQuit[{}[[10]], Power::infy]
Part::partw: Part 10 of {} does not exist. >>
Out[6]= {}[[10]]
请注意,由于消息与Power::infy
不匹配,内核未退出。但请考虑:
In[7]:= checkQuit[1/0, Power::infy]
Power::infy: Infinite expression 1/0 encountered. >>
checkQuit::quit: The kernel is being shut down!
此处内核退出,因为出现了指示的消息。可以过滤多条消息甚至是预定义的消息组 - 有关详细信息,请参阅Check。
答案 2 :(得分:7)
除了其他答案,您可能需要使用以下方式进行调查:
$MessagePrePrint
允许您在触发任何消息时执行代码。
例如,您可以对此进行评估:
$MessagePrePrint := (Print[Stack[_]]; Dialog[])
打印正在评估的代码的评估堆栈(有时非常大!)。然后,对话框功能将您置于子评估循环中,允许您检查值 变量。要退出对话框循环,您可以评估:
Return[]
将您带回主循环(主要评估然后完成或中断 在新消息)。
答案 3 :(得分:5)
您写道:
首先,我希望我的笔记本停止运行断言 错误。
您可以按照以下方式定义$AssertFunction
来执行此操作:
$AssertFunction := Quit[] & ;
现在内核在断言失败时退出:
<< ExampleData`FunctionWithAssert`
Compute[ 1.0]
(*=> kernel quits*)
或者,您可以以相同的方式使用Interrupt
:
$AssertFunction := Interrupt[] & ;
它允许您中止评估或输入subsession(与Arnoud的答案中的Dialog[]
相同)。
您还可以扩展此方法来打印失败的断言:
$AssertFunction := (Print[HoldForm @@ #]; Interrupt[]) &;