1

I wish to intercept assigning new values for the In variable.

I have tried to do this by defining UpValues for In but it does not help in this case:

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]]]

Is it possible to intercept it?

P.S. This question has arisen as a part of previous question on the stage when Mathematica creates new Symbols.

EDIT

I would wish to intercept explicitly the assignment new DownValue for the In variable. $Pre executes after this assignment and after creating all new Symbols in the current $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
Community
  • 1
  • 1
Alexey Popkov
  • 9,355
  • 4
  • 42
  • 93
  • What symbols are you trying to prevent being created? If you pose what you really want to do, maybe someone will have a nice solution for that. I don't see trying to hook into `In` having a productive outcome. – Brett Champion Apr 11 '11 at 22:07
  • @Brett My goals are primarily exploratory at this moment. I am just trying to collect the most powerful instruments for analysis and control of the evaluation. – Alexey Popkov Apr 11 '11 at 22:22
  • 1
    One approach which allows in some cases to have a greater control over the evaluation is to construct custom evaluators on top of Mathematica's evaluator. This may induce a significant overhead, but that is a price for flexibility. One example I posted in this thread: http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/e9e7551253d39031 (may have bugs). In some cases, `Stack` can be used to get evaluation that is otherwise hard or impossible to implement: http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/1982c4a8024e6c84 – Leonid Shifrin Apr 12 '11 at 08:19

1 Answers1

4

Have you looked at $Pre and $PreRead?

$Pre is a global variable whose value, if set, is applied to every input expression.

$PreRead is a global variable whose value, if set, is applied to the text or box form of every input expression before it is fed to Mathematica.

UPDATE (now with better example)

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\\)"

UPDATE 2

Replace $Pre with $PreRead in my code above and you get close to what you want, I believe:

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

It's not possible to intercept In at the *Value level because the Kernel is simply not interacting with In via value manipulation in "top-level" Mathematica code.

Michael Pilat
  • 6,480
  • 27
  • 30
  • Thank you for the point! But this question is about intercepting assignments to `In`. – Alexey Popkov Apr 11 '11 at 19:42
  • 2
    `$Pre` and `$PreRead` can be used to do that, I updated with an example. If you just want to snoop, you can make `$Pre` return the argument unchanged, after you inspect it. – Michael Pilat Apr 11 '11 at 20:39
  • @Michael Please see EDITed part in my question. – Alexey Popkov Apr 11 '11 at 21:35
  • Also, you can use `$Line` to know which In value is going to be set. – Szabolcs Apr 11 '11 at 21:43
  • It seems that you are right: probably the values to `In` are assigned outside of the *Mathematica*'s Main Loop although we can manipulate them by using top-level code. I accept your response. – Alexey Popkov Apr 12 '11 at 09:35
  • The only little addition about your function for `$Pre`: it incorrectly work with inputs having `Head` `Sequence`. For making it perfect `HoldFirst` should be replaced by `HoldAllComplete`. – Alexey Popkov Apr 12 '11 at 09:38