代码之家  ›  专栏  ›  技术社区  ›  Yaroslav Bulatov

检测DownValue/OwnValue冲突

  •  7
  • Yaroslav Bulatov  · 技术社区  · 14 年前

    偶尔我会遇到以下场景——一个过程使用全局函数 f[x] 做一些计算,同时另一个程序做 f=5 它会开启所有后续呼叫 f[x] 进入之内 5[x]

    我知道如何本地化变量,但我更喜欢在开发早期使用全局变量。

    我想不出一个合理的理由把自己的价值观和贬低的价值观混为一谈。当发生上述情况时,是否有方法实现警告消息?

    除了以下提示外,默认上下文可以在“单元格选项/计算选项/单元格上下文”下的“选项检查器”中找到

    2 回复  |  直到 14 年前
        1
  •  11
  •   Michael Pilat    14 年前

    你可以用 Protect[f] 避免(任何形式的)进一步的任务 Unprotect[f] 再次允许他们。

    你也可以用up值做一些简单的黑客来防止 Set[f, ...] 把自己的价值观 f 但仍然允许向下赋值,而不必使用 Protect / Unprotect :

    In[76]:= ClearAll[f]
    
    In[77]:= f /: Set[f, x_] := x
    
    In[78]:= f = 7
    
    Out[78]= 7
    
    In[79]:= f
    
    Out[79]= f
    
    In[80]:= f[x_] := x + 1
    
    In[81]:= f[1]
    
    Out[81]= 2
    

    以上内容透明地阻止了 Set f型 . 发布实际消息也很简单:

    In[93]:= f::noov = "Blocked attempt to assign `1` as an OwnValue of f";
    
    In[94]:= f /: Set[f, x_] := (Message[f::noov, x]; x)
    
    In[95]:= f = 7
    
    During evaluation of In[95]:= f::noov: Blocked attempt to assign 7 as
       an OwnValue of f
    
    Out[95]= 7
    
        2
  •  3
  •   WReach    14 年前

    这并不能回答最初关于生成警告消息的问题,但是 Formal Symbols 很方便用作全局符号。它们是自动保护的,因此不能意外地重新定义。使用按键输入正式符号 <ESC>$f</ESC> ,其中 f 可以是任何一封信。缺点是输入符号需要四次按键,而不是一次。