wolfram mathematica - How to make an analog of InString[]? -
i have discovered instring[]
not work in mathlink
mode when sending input enterexpressionpacket
header. need define own function returns previous input line. 1 way have developed here
not work in cases:
in[1]:= unevaluated[2 + 2] with[{line = $line - 1}, holdform[in[line]]] /. (downvalues[in]) out[1]= unevaluated[2 + 2] out[2]= 2 + 2
this because ruledelayed
has no holdallcomplete
attribute. adding attribute makes ok:
in[1]:= unprotect[ruledelayed]; setattributes[ruledelayed, holdallcomplete]; protect[ruledelayed]; unevaluated[2 + 2] with[{line = $line - 1}, holdform[in[line]]] /. downvalues[in] out[4]= unevaluated[2 + 2] out[5]= unevaluated[2 + 2]
but modifying built-in functions not idea. there better way this?
it seems have solved problem. here function:
in[1]:= getlastinput := module[{num, f}, f = function[{u, v}, {u /. {in -> num, holdpattern -> first}, holdform[v]}, holdallcomplete]; first@cases[ block[{ruledelayed = f}, downvalues[in]], {$line - 1, x_} -> x, {1}, 1]] in[2]:= unevaluated[2+2] getlastinput out[2]= unevaluated[2+2] out[3]= unevaluated[2+2]
and have got answer question on instring
in mathlink
mode todd gayley (wolfram research):
instring assigned when using entertextpacket, not enterexpressionpacket. there no string form of input when sending enterexpressionpacket (whose content is, definition, expression).
edit:
i have found code not work input expressions head evaluate
. solution replace holdform
holdcomplete
in code:
getlastinput := module[{num, f}, f = function[{u, v}, {u /. {in -> num, holdpattern -> first}, holdcomplete[v]}, holdallcomplete]; first@cases[ block[{ruledelayed = f}, downvalues[in]], {$line - 1, x_} -> x, {1}, 1]]
this works well. approach unprotect holdform
, set attribute holdallcomplete
on it. i'm wondering why holdform
not have attribute default?
edit 2:
in comments main question leonid shifrin suggested better solution:
getlastinput := block[{ruledelayed},setattributes[ruledelayed,holdallcomplete]; with[{line=$line-1},holdcomplete[in[line]]/.downvalues[in]]]
see comments details.
edit 3: last code can made better replacing holdcomplete
double holdform
:
getlastinput := block[{ruledelayed},setattributes[ruledelayed,holdallcomplete]; with[{line=$line-1},holdform@holdform[in[line]]/.downvalues[in]]]
the idea taken presentation robby villegas of wolfram research @ 1999 developer conference. see subsection "holdcompleteform: non-printing variant of holdcomplete (just holdform hold)" in "working unevaluated expressions" notebook posted here.
Comments
Post a Comment