问题描述
我想弄清楚Message
行为的逻辑.
I am trying to figure out the logic of Message
behavior.
考虑评估以下内容:
On[]
Sin[1,1]
评估上述内容后,您将获得大约 830 (!) 个 Messages
(在 Mathematica 7 中).
After evaluating the above you will get about 830 (!) Messages
(in Mathematica 7).
所有这些Messages
都是在制作过程中出现的:
All these Messages
have arisen during producing the one:
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
的评估.
corresponds to finishing of the work of internal Mathematica's Message
function. Most of the other Messages
go from evaluation of $NewMessage
and $MessagePrePrint
.
我的问题是:
1) 为什么没有Message
生成的无限循环?如果调用 Message[Sin::argx,Sin,2]
会产生超过 830 条其他 Messages
为什么它们每个不会产生相似数量的 Messages
>?如何模拟这种行为(通过编写 Message
的模拟)?
1) Why there are no infinite loop of Message
generation? If calling Message[Sin::argx,Sin,2]
produces more than 830 other Messages
why each of them does not produce similar number of Messages
? How such behavior can be simulated (by writing an analog of Message
)?
2) 是否可以强制 Message
在跟踪模式下调用时不产生任何额外的 Messages
(我的意思是评估 On 后的模式)[]
)?
2) Is it possible to force Message
do not produce any additional Messages
when it is called in the tracing mode (I mean the mode after evaluating On[]
)?
推荐答案
我似乎找到了一种用内置函数 Message
实现我想要的方法:
It seems that I have found one way to achieve with built-in function Message
what I want:
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 负载仍然很高,正如您从时序中看到的那样.
The only problem with the above is that CPU load is still high as you can see from the timings.
其他经过测试的案例也能正常工作:
Other tested cases also work correctly:
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 的 帮助.
Thanks to Mr.Wizard for his help.
这篇关于Message 内部的逻辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!