(MathLink)正确处理从属内核生成的消息 [英] (MathLink) Correct handling of Messages generated by slave kernel

查看:102
本文介绍了(MathLink)正确处理从属内核生成的消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用从属内核通过MathLink时,我无法正确解析TextPacket.特别是当此类数据包与从属内核生成的Message相对应时,我根本不了解如何正确处理它.我需要这样的Messages来打印在评估笔记本中,就像它们是由主内核生成的一样(但带有一些标记以表明它来自从属内核).而且我需要将与Message相对应的TextPacket与仅与Print[]命令分开.后者我也需要正确解析,将它们打印在评估笔记本中,并带有一点标记,即它是从属内核的.

When working through MathLink with slave kernel I have a problem with correct parsing TextPackets. In particular when such packet corresponds to a Message generated by the slave kernel I do not understand how to handle it correctly at all. I need such Messages to be printed in the evaluation notebook as if they were generated by master kernel (but with some mark to make clear that it comes from the slave). And I need to separate TextPackets corresponding to Messages from just to Print[] commands. The latter I need to parse correctly too, printing them in the evaluation notebook with a little mark that it is from the slave kernel.

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

Here is an example of what happens:

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]]

默认情况下,MessageMathLink的形式出现:

The Message by default comes through MathLink in the form:

TextPacket[                                 1
Power::infy: Infinite expression - encountered.
                                 0]

看起来很丑.使我发现更好的唯一方法是在从属内核中进行评估

It looks ugly. The only way to make it better I have found is to evaluate in the slave kernel

$MessagePrePrint = InputForm;

但是我认为应该有更直接的解决方案.特别是当以这种方式处理时,我得到的TextPacket里面有HoldForm s:

But I think there should be more straightforward solution. In particular when dealing this way I get TextPackets with HoldForms inside:

TextPacket[Power::infy: Infinite expression HoldForm[0^(-1)] encountered.]

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

I do not know how to convert such string into a form appropriate for printing as a Message.

P.S.这个问题来自

P.S. This question comes from that question.

推荐答案

我想分享一个由Todd Gayley(Wolfram Research)提出的关于给定问题的不错的技巧.也许对某人来说,这对我也将是有用的.这种技巧可以相当优雅地解决问题.

I would like to share a nice hack proposed by Todd Gayley (Wolfram Research) in connection with the given question. Perhaps for somebody it will be useful as also for me. This hack solves the problem in question in rather elegant way.

一种技术是将 在OutputForm上的FormatType 计算,但覆盖 临时处理消息 切换到StandardForm,以便仅 消息输出又回来了 StandardForm:

One technique is to leave the FormatType at OutputForm for computations, but override the handling of Message to temporarily switch to StandardForm, so that only Message output comes back in 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以获取内容的内容. 信息.要将其作为消息单元格打印在 笔记本:

You will get back an ExpressionPacket for the content of a message. To print that as a Message cell in the notebook:

cell = Cell[<the ExpressionPacket>, "Message", "MSG"]
CellPrint[cell]

高级方法:所有内容都在StandardForm中打印

要获得除StandardForm中返回的输出以外的所有内容,我们可以通过特殊方式在从属内核中重新定义变量$Pre$Post(应在从属内核中评估以下代码):

Advanced approach: everything is printed in the StandardForm

For having everything except output returned in StandardForm we could redefine variables $Pre and $Post in the slave kernel in a special way (the following code should be evaluated in the slave kernel):

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];

这篇关于(MathLink)正确处理从属内核生成的消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆