在使用从内核的MathLink时,我遇到了正确解析TextPacket的问题,特别是当这样的数据包对应于从内核生成的Message时,我根本不知道如何正确处理它。我需要在评估笔记本中打印这样的Messages,就像它们是由主内核生成的一样(但要有一些标记,以表明它来自从内核)。我需要将对应于Message的命令从Print[]命令中分离出来。后者我也需要正确解析,将它们打印在评估笔记本上,并带有一个小标记,表明它来自从内核。
下面是一个发生情况的示例:
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]]默认情况下,Message以以下形式通过MathLink提供:
TextPacket[ 1
Power::infy: Infinite expression - encountered.
0]它看起来很丑陋。我发现唯一能让它变得更好的方法是在从内核中求值
$MessagePrePrint = InputForm;但我认为应该有更直接的解决方案。特别是,当我用这种方式处理时,我得到了内部带有HoldForms的TextPackets:
TextPacket[Power::infy: Infinite expression HoldForm[0^(-1)] encountered.]我不知道如何将这样的字符串转换为适合作为Message打印的形式。
附注:此问题来自that问题。
发布于 2011-03-01 09:25:59
我想分享一个由Todd Gayley (Wolfram Research)提出的关于给定问题的很好的技巧。也许对某些人来说,它也会对我有用。这个技巧以一种相当优雅的方式解决了问题。
一种技术是将FormatType留在OutputForm进行计算,但覆盖消息处理以临时切换到StandardForm,这样只有消息输出在StandardForm中返回:
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]
]
]]您将得到一个消息内容的ExpressionPacket。要将其打印为笔记本中的消息单元格,请执行以下操作:
单元格=单元格,“消息”,“消息”CellPrintcell
高级方法:所有内容都打印在StandardForm中
为了在StandardForm中返回除输出之外的所有内容,我们可以在从内核中以一种特殊的方式重新定义变量$Pre和$Post (以下代码应该在从内核中计算):
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];发布于 2011-02-20 01:01:32
表达式始终以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]]https://stackoverflow.com/questions/4998561
复制相似问题