【问题标题】:(MathLink) Correct handling of Messages generated by slave kernel(MathLink) 正确处理从内核生成的消息
【发布时间】:2011-02-14 23:33:26
【问题描述】:

在使用从属内核处理 MathLink 时,我在正确解析 TextPackets 时遇到问题。特别是当此类数据包对应于从属内核生成的Message 时,我根本不明白如何正确处理它。我需要在评估笔记本中打印这样的Messages,就好像它们是由主内核生成的一样(但有一些标记表明它来自从属内核)。我需要将与Messages 相对应的TextPackets 与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;

但我认为应该有更直接的解决方案。特别是在以这种方式处理时,我得到TextPackets 和HoldForms 里面:

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

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

附:这个问题来自that问题。

【问题讨论】:

    标签: wolfram-mathematica mathlink


    【解决方案1】:

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

    一种技巧是离开 OutputForm 处的 FormatType 为 计算,但覆盖 消息处理临时 切换到 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 的内容 信息。将其打印为消息单元格 笔记本:

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

    高级方法:所有内容都打印在 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];
    

    【讨论】:

      【解决方案2】:

      表达式总是出现在 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]]
      

      【讨论】:

      • 但是有没有比实现额外的盒子渲染器更好的方法?
      • 如何使用 ToString 并处理结果,像这样$MessagePrePrint = StringReplace[ToString[InputForm[#]], "HoldForm[" ~~ Shortest[x___] ~~ "]" :&gt; x] &amp;
      • 它更简单,但下标、下标和命名字符在InputForm 中看起来很难看。我希望有一些“魔术”功能可以强制从内核以方便的形式发送消息(例如作为整个Cell 内容而无需进一步渲染)。如果创建盒子渲染器的想法别无选择,我需要一些帮助。例如,我不明白为什么会产生错误:ToExpression[ToString[ToBoxes[HoldForm[Infinity - Infinity]]]](它来自为输入 Infinity - Infinity 生成的消息)。
      • @AlexeyPopkov 问题是 ToString 默认使用的是 OutputForm,保证可以使用 ToExpression,你要么需要 StandardForm,要么需要 InputForm。喜欢ToExpression[ ToString[ToBoxes[HoldForm[Infinity - Infinity]], InputForm]]
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-27
      • 1970-01-01
      • 1970-01-01
      • 2012-04-27
      • 2013-08-31
      • 1970-01-01
      • 2016-03-14
      相关资源
      最近更新 更多