如何全局关闭阴影消息(符号:: shdw)?还是其他任何"良好做法"的建议?

pha*_*234 5 wolfram-mathematica

我有以下情况:

On[t::shdw]

Message[t::shdw,"t","Foobar","Dork"]
-> t::shdw: Symbol t appears in multiple contexts Foobar; definitions in context Dork may shadow or be shadowed by other definitions. >>

Off[t::shdw]
Message[t::shdw,"t","Foobar","Dork"]
-> **No Warning**

<<MASStoolbox`
-> t::shdw: Symbol t appears in multiple contexts {MASStoolbox`MASS`,Global`}; definitions in context MASStoolbox`MASS` may shadow or be shadowed by other definitions. >>
Run Code Online (Sandbox Code Playgroud)

怎么可能?是否OnOff加载软件包时只影响当前笔记本电脑并没有任何影响?如果是这样,怎么能摆脱像这样的消息呢?如何处理阴影错误?

Leo*_*rin 7

您观察到的原因是该语句Off[t::shdw]禁用了t当前在其他程序包加载期间创建的符号的阴影消息$ContextPath,而不是另一个符号的阴影消息t.t如果您不想看到它,则应该禁用该秒的阴影消息.这是一个例子:

In[1]:= Off[Test1`a::shdw]
In[2]:= 
BeginPackage["Test`"]
a
EndPackage[]

Out[2]= Test`
Out[3]= a

In[5]:= BeginPackage["Test1`"]
a
EndPackage[]

Out[5]= Test1`
Out[6]= a
Run Code Online (Sandbox Code Playgroud)

这里没有生成任何消息.

但是,一般情况下,我不想禁用阴影消息,因为阴影是一个严重的问题.阴影只是意味着符号搜索路径($ContextPath)上当前有多个上下文,包含具有相同(短)名称的符号.基本上,如果符号被遮蔽,并且您通过其短名称(即没有包含包的符号)引用它,则无法保证实际使用具有相同短名称的几个符号中的哪一个.因此,正确处理这种情况的方法是完全避免阴影,这总是可能的,如果不总是方便的话.

避免阴影的最简单方法是将所需的包加载到包的私有部分,该部分从该行开始Begin["`Private`"].你Needs[your-package]一如既往地打电话来做到这一点.这样,加载的包的上下文不会$ContextPath与包的上下文一起保留.最糟糕的情况是,您需要加载两个包含冲突符号的包.一种方法是为其中一个构造一个包装器包,它将私下加载它并重命名冲突的符号.这可能不方便,因为您必须重命名包中的所有函数,即使那些不冲突的函数也是如此.以下是更灵活的变体示例:

第一包:

BeginPackage["Test`"];
g[x_?NumericQ] := x^2;
EndPackage[];
Run Code Online (Sandbox Code Playgroud)

第二包:

BeginPackage["Test1`"];
g[x_?NumericQ] := x^3;
EndPackage[]
Run Code Online (Sandbox Code Playgroud)

主要包装:

BeginPackage["Main`"];
f::usage = "A test function of a single  argument";
Begin["`Private`"];

Block[{$ContextPath = $ContextPath},
  Needs["Test`"];
  (* Define first delegate private function *)
  g1 = Symbol["g"]];


Block[{$ContextPath = $ContextPath},
  Needs["Test1`"];
  (* Define second delegate private function *)
  g2 = Symbol["g"];
];

f[x_] := g1[x]*g2[x]
End[]
EndPackage[]
Run Code Online (Sandbox Code Playgroud)

现在,只要系统知道在哪里找到你的包:

In[2]:= Needs["Main`"]

In[3]:= f[x]
Out[3]= Test`g[x] Test1`g[x]

In[4]:= f[2]
Out[4]= 32
Run Code Online (Sandbox Code Playgroud)

我们对同一个公共函数使用了两个冲突的符号.使用Block上面的方法来本地化使用第一个或第二个定义的代码g.请注意,此方法存在一些不便之处,因为我们需要使用Symbol["your-symbol-name"],将解析延迟到运行时.

一个更简单的方法是用长名称来引用符号.在上面,我们可以使用Test`g,Test1`g然后不需要重型机械.然而,这有点不太灵活,因为您必须将符号的上下文"硬编码"到代码中.

  • +1我只是打字(几乎)完全相同的答案...一个评论:如果幻影真的想要关闭所有阴影消息,他应该使用`Off [General :: shdw] (4认同)