首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >(MathLink)正确处理从内核生成的消息

(MathLink)正确处理从内核生成的消息
EN

Stack Overflow用户
提问于 2011-02-15 07:33:27
回答 2查看 567关注 0票数 3

在使用从内核的MathLink时,我遇到了正确解析TextPacket的问题,特别是当这样的数据包对应于从内核生成的Message时,我根本不知道如何正确处理它。我需要在评估笔记本中打印这样的Messages,就像它们是由主内核生成的一样(但要有一些标记,以表明它来自从内核)。我需要将对应于Message的命令从Print[]命令中分离出来。后者我也需要正确解析,将它们打印在评估笔记本上,并带有一个小标记,表明它来自从内核。

下面是一个发生情况的示例:

代码语言:javascript
复制
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提供:

代码语言:javascript
复制
TextPacket[                                 1
Power::infy: Infinite expression - encountered.
                                 0]

它看起来很丑陋。我发现唯一能让它变得更好的方法是在从内核中求值

代码语言:javascript
复制
$MessagePrePrint = InputForm;

但我认为应该有更直接的解决方案。特别是,当我用这种方式处理时,我得到了内部带有HoldForms的TextPackets:

代码语言:javascript
复制
TextPacket[Power::infy: Infinite expression HoldForm[0^(-1)] encountered.]

我不知道如何将这样的字符串转换为适合作为Message打印的形式。

附注:此问题来自that问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-01 09:25:59

我想分享一个由Todd Gayley (Wolfram Research)提出的关于给定问题的很好的技巧。也许对某些人来说,它也会对我有用。这个技巧以一种相当优雅的方式解决了问题。

一种技术是将FormatType留在OutputForm进行计算,但覆盖消息处理以临时切换到StandardForm,这样只有消息输出在StandardForm中返回:

代码语言:javascript
复制
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 (以下代码应该在从内核中计算):

代码语言:javascript
复制
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];
票数 4
EN

Stack Overflow用户

发布于 2011-02-20 01:01:32

表达式始终以HoldForm格式提供,但使用默认$MessagePrePrint时不会呈现该表达式。尝试评估

代码语言:javascript
复制
HoldForm[1/0]

InputForm[%]

实现所需行为的一种方法是实现自己的长方体渲染器。要查看渲染器必须处理的内容,请设置

代码语言:javascript
复制
$MessagePrePrint = ToBoxes[{##}] &

在奴隶身上。如下所示:

代码语言:javascript
复制
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]]
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4998561

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档