Detecting DownValue/OwnValue conflicts
Occasionally I run into the following scenario -- one procedure uses a global function f[x]
to do some computation, meanwhile another procedure does f=5
which turns all subsequent calls f[x]
into 5[x]
I know about localizing variables, but I prefer to use global variables early in the development.
开发者_如何学GoI can't think of a legitimate reason to mix OwnValues and DownValues. Is there a way to implement a warning message when situation like above happens?
In addition to tips below, default context can be found in OptionsInspector under Cell Options/Evaluation Options/CellContext
You can use Protect[f]
to avoid further assignments (of any kind) and Unprotect[f]
to allow them again.
You could also do some simple hackery with up-values to prevent Set[f, ...]
from actually putting own-values on f
but still allowing the assignment of down-values without having to use 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
The above transparently blocks the use of Set
on f
. Issuing an actual message is straightforward too:
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
This doesn't answer the original question about generating a warning message, but Formal Symbols are handy for use as global symbols. They are automatically protected and therefore cannot be accidentally redefined. You enter a formal symbol using the keystrokes <ESC>$f</ESC>
, where f
can be any letter. The disadvantage is that it takes four keystrokes to enter the symbol instead of one.
精彩评论