Message internals的逻辑

时间:2011-04-24 18:07:14

标签: wolfram-mathematica

我试图找出Message行为的逻辑。

考虑以下评估:

On[]
Sin[1,1]

评估完上述内容后,您将获得大约830(!)Messages(在 Mathematica 7中)。

所有这些Messages在制作过程中出现:

Sin::argx: Sin called with 2 arguments; 1 argument is expected. >>

(这是一个但最后Message)。

最后Message

Message::trace: Message[Sin::argx,Sin,2] --> Null. >>

对应于完成内部 Mathematica Message函数的工作。大多数其他Messages来自对$NewMessage$MessagePrePrint的评估。

我的问题是:

1)为什么没有Message代的无限循环?如果调用Message[Sin::argx,Sin,2]产生超过830个其他Messages,为什么每个Messages都不会产生相似数量的Message?如何模拟这种行为(通过编写Message的模拟?)

2)在跟踪模式中调用它时,是否可以强制Messages不产生任何额外的On[](我的意思是评估{{1}}后的模式)?

2 个答案:

答案 0 :(得分:0)

我不明白为什么有必要使用On打开所有邮件。你不仅可以激活你需要的子集。 “更多信息”部分中On的参考页面列出了您可能会发现有用的各种类别。如果您选择按照规定继续操作,则可以在On[]之后立即关闭跟踪消息来禁止跟踪消息:

On[]; Off[General::trace];
Sin[1, 1]

这只输出两条消息。因此,您看到的830条消息是::跟踪消息,并且源于执行一些不一定与消息相关的顶级代码,可能是排版...

答案 1 :(得分:0)

似乎我找到了一种方法来实现内置函数Message我想要的东西:

Unprotect[Message];
Message[_, HoldForm[Block[List[$MyMagicalTag$, ___], _]], _] := Null;
Message[args___] /; 
   Block[{$MyMagicalTag$, Message}, Not@TrueQ[inMsg]] := 
  Block[{$MyMagicalTag$, inMsg = True, lastargs = HoldComplete[args]},
    Message[args]];
Message[args___] /; 
   Block[{$MyMagicalTag$, 
     Message}, (inMsg && (HoldComplete[args] =!= lastargs))] := Null;
Protect[Message];

现在事情按预期工作:

In[6]:= On[]
In[7]:= Sin[1,1]//AbsoluteTiming
During evaluation of In[7]:= Message::trace: Message[Sin::argx,Sin,2] --> Block[{$MyMagicalTag$,inMsg=True,lastargs=HoldComplete[Sin::argx,Sin,2]},Message[Sin::argx,Sin,2]]. >>
During evaluation of In[7]:= Sin::argx: Sin called with 2 arguments; 1 argument is expected. >>
During evaluation of In[7]:= AbsoluteTiming::trace: AbsoluteTiming[Sin[1,1]] --> {0.1502160,Sin[1,1]}. >>
Out[7]= {0.1502160,Sin[1,1]}

上面唯一的问题是,从时间上看,CPU负载仍然很高。

其他测试案例也能正常运作:

In[8]:= 1+1//AbsoluteTiming
During evaluation of In[8]:= Plus::trace: 1+1 --> 2. >>
During evaluation of In[8]:= AbsoluteTiming::trace: AbsoluteTiming[1+1] --> {0.0400576,2}. >>
Out[8]= {0.0400576,2}

感谢Mr.Wizard的help