2011-04-24 63 views
4

我想弄清楚的Message行为逻辑。消息的逻辑内部构件

考虑以下评价:

On[] 
Sin[1,1] 

评估上面你会得到后约830 Messages(在数学 7)(!)。

所有这些都Messages产生一个中出现了:

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

(这是一个,但最后Message)。

最后Message

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

对应于内部数学Message功能的工作结束。大多数其他Messages的去从$NewMessage$MessagePrePrint评价。

我的问题是:

1)为什么有Message一代没有无限循环?如果在调用Message[Sin::argx,Sin,2]产生其他830多家Messages为什么他们每个人不产生Messages类似的号码是多少?如何模拟这种行为(编写Message的模拟)?

2)是否有可能强制Message在追踪模式下调用时不会产生任何额外的Messages(我的意思是评估On[]后的模式)?

回答

0

看来,我已经找到了实现与单向内置功能Message我想:

Unprotect[Message]; 
Message[_, HoldForm[Block[List[$MyMagicalTag$, ___], _]], _] := Null; 
Message[args___] /; 
    Block[{$MyMagicalTag$, Message}, [email protected][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

0

我不理解为什么有必要与On打开所有的消息。你不仅可以激活你需要的子集。 “更多信息”部分中的参考页面On列出了您可能会觉得有用的各种类别。如果你选择继续为所述,您可以通过On[]后立即明确地将其关闭抑制跟踪消息:

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

该输出只有两个消息。因此,你看到的消息的830 ::跟踪消息和一些顶级代码执行的起源是没有必然的关系,可能是排版信息...

+1

我已经调查了这种情况下的一些照顾和结果在我的问题中解释。所有这些::跟踪'消息'在评估'Message [Sin :: argx,Sin,2]'时产生。最后有一些对MakeBoxes的调用,但它又是在最后一条消息Message :: trace:Message [Sin :: argx,Sin,2] - > Null之前。 >> '。你的建议是关闭追踪。我需要关闭“Message”内部的跟踪和/或理解为什么没有无限循环。 – 2011-04-25 02:46:30

+0

关于这个问题的原因,考虑例如'在[Block]; Sin [1,1]'。如果在一个复杂的程序里面生成一些'Message',并且我想跟踪一些Symbol的评估,我可以从Message的评估中得到垃圾信息。我只需要关闭“消息”内部的跟踪,而不是周围的代码。 – 2011-04-25 03:21:13

+0

@Alexey我不认为你所要求的是可能的,因为跟踪不区分内部程序是否使用该符号。我刚刚注意到,在[Block]上运行'Sin [1,1]'这些不需要的消息第二次消失,这可能会有所帮助。 – Sasha 2011-04-25 13:46:14