为什么我要两次评估这个?

Mr.*_*ard 15 wolfram-mathematica

我无法弄清楚为什么我必须两次评估(在Mathematica 7中)进行分配.

第一次评估:

Unprotect[Rule];
Attributes[Rule]
pp = Plot | LogLinearPlot | ListPlot | ParametricPlot3D;
(h : pp)[True -> False] ^:= Print["Irrelevant data"]

(*

Out[2]= {SequenceHold}

During evaluation of In[1]:= UpSetDelayed::write: Tag Rule in (h:Plot|LogLinearPlot|ListPlot|ParametricPlot3D)[True->False] is Protected. >>

Out[4]= $Failed

*)
Run Code Online (Sandbox Code Playgroud)

从中可以看出Out[2]= {SequenceHold},Unprotect[Rule]工作,但错误消息另有说明.如果我第二次评估单元格,则赋值并且不会生成错误.

为什么会这样?

Sas*_*sha 16

您可能知道,Mathematica会加载实现其某些功能的二进制MX文件.这些MX文件存储实现以及定义和属性.

这是阴险的,但Unprotect[Rule]Mathematica新加载的MX文件已经取消了,这就解释了为什么它第二次工作.因为Mathematica已经加载了所需的所有MX文件.

如果您首先评估表达式中的所有符号,那么它就会停止抱怨:

{Unprotect, Rule, Attributes, Plot, LogLinearPlot, ListPlot, 
  ParametricPlot3D, True, False, Print};
Unprotect[Rule];
Attributes[Rule];
pp = Plot | LogLinearPlot | ListPlot | ParametricPlot3D;
(h : pp)[True -> False] ^:= Print["Irrelevant data"]
Run Code Online (Sandbox Code Playgroud)

编辑需要进行第一次评估,以便在取消保护之前触发所有自动加载Rule.

  • @Sasha感谢您分享这些信息.从用户的角度来看,我仍然将其归类为一个错误 - 这与关于符号保护的非常一般的语言语义以及文档相矛盾.一旦生产中使用的第三方mma代码的数量变得很大(假设这种情况发生),像这样的情况将成为一个真正的问题.至少,IMO需要正式的编码指南,其中包含一些内置函数列表,这些函数应该永远不会被用户修改,即这些修改将导致未定义的行为. (5认同)
  • @WReach .mx文件加载不能通过`Stub`工作.添加一个定义,以便评估符号将加载.mx文件(然后清除特殊定义.) (3认同)
  • 不完全,它包含符号的属性.有点像`SetAttributes [a,Protected]; DumpSave [FileNameJoin [{$ HomeDirectory,"Desktop","tmp.mx"}],a];`然后`Unprotect [a]; 获取[FileNameJoin [{$ HomeDirectory,"Desktop","tmp.mx"}]]; a = 1` (2认同)