Wolfram mathematica (MathLink)正确处理从内核生成的消息
使用从内核处理Wolfram mathematica (MathLink)正确处理从内核生成的消息,wolfram-mathematica,mathlink,Wolfram Mathematica,Mathlink,使用从内核处理MathLink时,我在正确解析textpacks时遇到问题。特别是当这样的数据包对应于从内核生成的消息时,我根本不知道如何正确处理它。我需要将这些消息打印在评估笔记本中,就像它们是由主内核生成的一样(但带有一些标记以明确它来自从内核)。我需要从just toPrint[]命令中分离对应于Messages的TextPackets。后者我也需要正确解析,将它们打印在评估笔记本中,并带有一点标记,表明它来自从内核 以下是发生的情况的示例: link = LinkLaunch[First
MathLink
时,我在正确解析textpack
s时遇到问题。特别是当这样的数据包对应于从内核生成的消息时,我根本不知道如何正确处理它。我需要将这些消息
打印在评估笔记本中,就像它们是由主内核生成的一样(但带有一些标记以明确它来自从内核)。我需要从just toPrint[]
命令中分离对应于Message
s的TextPacket
s。后者我也需要正确解析,将它们打印在评估笔记本中,并带有一点标记,表明它来自从内核
以下是发生的情况的示例:
link = LinkLaunch[First[$CommandLine] <> " -mathlink"]
Print@LinkRead[link]
LinkWrite[link,
Unevaluated[EnterExpressionPacket[Print[a]; 1/0; Print[b]]]]
While[Not@MatchQ[packet = LinkRead[link], InputNamePacket[_]],
Print[packet]]
它看起来很丑。我发现,使其更好的唯一方法是在从内核中进行评估
$MessagePrePrint = InputForm;
但我认为应该有更直接的解决办法。特别是当以这种方式处理时,我在HoldForm
s中得到TextPacket
s:
TextPacket[Power::infy: Infinite expression HoldForm[0^(-1)] encountered.]
我不知道如何将这样的字符串转换成适合打印为消息的格式
注意:这个问题来自于问题。表达式总是以HoldForm形式出现,但默认的$MessagePrePrint不是
提供。尝试评估
HoldForm[1/0]
InputForm[%]
实现所需行为的一种方法是实现自己的长方体渲染器。要查看渲染器必须进行处理,请设置
$MessagePrePrint = ToBoxes[{##}] &
在奴隶时代。像这样:
link = LinkLaunch[First[$CommandLine] <> " -mathlink"]
Print@LinkRead[link]
LinkWrite[link,
Unevaluated[
EnterExpressionPacket[$MessagePrePrint = ToBoxes[{##}] &; Print[a];
1/0; Print[b]]]]
While[Not@MatchQ[packet = LinkRead[link], InputNamePacket[_]],
Print[packet]]
link=LinkLaunch[First[$CommandLine]“-mathlink”]
Print@LinkRead[连结]
LinkWrite[link,
未估价[
EnterExpressionPacket[$MessagePrePrint=tobox[{##}]&Print[a];
1/0;打印[b]]]
当[Not@MatchQ[packet=LinkRead[link],InputNamePacket[]],
打印[包]]
我想分享托德·盖利(Wolfram Research)针对给定问题提出的一个不错的解决方案。也许对某些人和我都有用。这个黑客以相当优雅的方式解决了这个问题
一种方法是离开
的OutputForm处的FormatType
计算,但覆盖
处理要临时发送的消息
切换到StandardForm,以便
消息输出返回
标准格式:
您将得到一个ExpressionPacket,用于
消息将其打印为
笔记本:
cell = Cell[<the ExpressionPacket>, "Message", "MSG"]
CellPrint[cell]
但是有没有比实现额外的框渲染器更好的方法呢?使用ToString并处理结果怎么样,比如说,像这样$MessagePrePrint=StringReplace[ToString[InputForm[#]],“HoldForm[“~~ Shortest[x#u#]~~”:>x]&
它更简单,但是下标,在InputForm
中,欠脚本和命名字符看起来很难看。我希望有一些“神奇”的功能,可以迫使从内核以方便的形式发送消息(例如,作为完整的单元格内容,而无需进一步渲染)。如果创建长方体渲染器的想法没有其他选择,我需要一些帮助。例如,我不明白为什么会产生错误:ToExpression[ToString[ToBox[HoldForm[Infinity-Infinity]]]]
(它来自为输入生成的消息Infinity-Infinity
)。@AlexeyPopkov问题是ToString默认使用OutputForm,这保证了与ToExpression一起工作,您要么需要标准表单,要么需要输入表单。像ToExpression[ToString[tobox[HoldForm[Infinity-Infinity]],InputForm]]
。
LinkWrite[link,
Unevaluated[EnterExpressionPacket[
Unprotect[Message];
Message[args___]:=
Block[{$inMsg = True, result},
SetOptions[$Output, FormatType->StandardForm];
result = Message[args];
SetOptions[$Output, FormatType->OutputForm];
result
] /; !TrueQ[$inMsg]
]
]]
cell = Cell[<the ExpressionPacket>, "Message", "MSG"]
CellPrint[cell]
SetOptions[$Output, {PageWidth -> 72, FormatType -> StandardForm}];
(*$inPost is needed for tracing mode compatibility
(could be switched on by evaluating On[] in the slave kernel)
in which Messages are printed during evaluation of $Post.*)
$inPost = False; Protect[$inPost];
$Pre := Function[inputexpr,
SetOptions[$Output, FormatType -> StandardForm];
Unevaluated[inputexpr], HoldAllComplete];
$Post := Function[outputexpr,
Block[{$inPost = True},
SetOptions[$Output, FormatType -> OutputForm];
Unevaluated[outputexpr]], HoldAllComplete];
Protect[$Pre]; Protect[$Post];
$inMsg = False; Protect[$inMsg];
Unprotect[Message];
Message[args___] /; $inPost := Block[{$inMsg = True},
SetOptions[$Output, FormatType -> StandardForm];
Message[args];
SetOptions[$Output, FormatType -> OutputForm]] /; ! $inMsg;
Protect[Message];