私は問題を解決したようです。関数は次のとおりです。
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]
そして、私はTodd Gayley(Wolfram Research)からモードInString
での質問に対する答えを得ました:MathLink
InStringは、EnterExpressionPacketではなく、EnterTextPacketを使用する場合にのみ割り当てられます。EnterExpressionPacketを送信するときの入力の文字列形式はありません(その内容は、定義上、すでに式です)。
編集:
私のコードはheadを使用した入力式では機能しないことがわかりましたEvaluate
。解決策は、私のコードで次のように置き換えるHoldForm
ことです。HoldComplete
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]]
これはうまく機能します。もう1つのアプローチは、保護を解除HoldForm
して属性を設定するHoldAllComplete
ことです。なぜHoldForm
デフォルトでこの属性がないのか疑問に思いますか?
編集2:
主な質問に対するコメントで、LeonidShifrinははるかに優れた解決策を提案しました。
getLastInput :=
Block[{RuleDelayed},SetAttributes[RuleDelayed,HoldAllComplete];
With[{line=$Line-1},HoldComplete[In[line]]/.DownValues[In]]]
詳細についてはコメントを参照してください。
編集3:HoldComplete
最後のコードはdouble
に置き換えることでさらに良くすることができますHoldForm
:
getLastInput :=
Block[{RuleDelayed},SetAttributes[RuleDelayed,HoldAllComplete];
With[{line=$Line-1},HoldForm@HoldForm[In[line]]/.DownValues[In]]]
このアイデアは、1999年の開発者会議でのWolframResearchのRobbyVillegasによるプレゼンテーションから取られています。ここに掲載されている「未評価の式の操作」ノートブックのサブセクション「HoldCompleteForm:HoldCompleteの非印刷バリアント(HoldFormが保持するのと同じように)」を参照してください。