如何拦截为In变量分配新值?

时间:2011-04-11 19:23:18

标签: wolfram-mathematica

我希望拦截为In变量分配新值。

我尝试通过为UpValues定义In来做到这一点,但在这种情况下它无效:

Unprotect[In];
In /: Set[In[line_], expr_] /; ! TrueQ[$InsideSet] := 
 Block[{$InsideSet = True}, 
  Print[HoldForm@HoldForm[expr]; Set[In[line], expr]]]
In /: SetDelayed[In[line_], expr_] /; ! TrueQ[$InsideSet] := 
 Block[{$InsideSet = True}, 
  Print[HoldForm@HoldForm[expr]; SetDelayed[In[line], expr]]]

是否可以拦截它?

P.S。当 Mathematica 创建新的Symbol时,此问题已作为previous question的一部分出现。

修改

我希望明确拦截In变量的赋值新DownValue。 $Pre在此分配后执行创建当前Symbol中的所有新$Context后执行

In[1]:= $Pre := (Print[Names["`*"]]; 
   Print[DownValues[In][[All, 1]]]; ##) &

In[2]:= a

During evaluation of In[2]:= {a}

During evaluation of In[2]:= {HoldPattern[In[1]],HoldPattern[In[2]]}

Out[2]= a

1 个答案:

答案 0 :(得分:4)

您是否看过$Pre$PreRead

$Pre是一个全局变量,其值(如果已设置)将应用于每个输入表达式。

$PreRead是一个全局变量,其值(如果已设置)将应用于每个输入表达式的文本或框形式,然后将其传送到Mathematica。

更新(现在使用更好的示例)

In[1]:= $Pre = 
  Function[{x}, Print["In[",$Line,"] is: ", Unevaluated[x]]; x, HoldFirst];

In[2]:= 2 + 2

During evaluation of In[2]:= In[2] is: 2+2

Out[2]= 4

In[3]:= InString[2]

During evaluation of In[3]:= In[3] is: InString[2]

Out[3]= "\\(2 + 2\\)"

更新2

在上面的代码中将$Pre替换为$PreRead,我相信你接近你想要的东西,我相信:

In[1]:= $PreRead = Function[{x}, Print[Names["`*"]]; x, HoldFirst]

Out[1]= Function[{x}, Print[Names["`*"]]; x, HoldFirst]

In[2]:= a = 1

During evaluation of In[2]:= {x}

Out[2]= 1

In[3]:= b = 2

During evaluation of In[3]:= {a,x}

Out[3]= 2

In级别拦截*Value是不可能的,因为内核根本不会通过“顶级”Mathematica代码中的值操作与In进行交互。