如何模拟 InString[]?
我发现使用 EnterExpressionPacket
标头发送输入时,InString[]
无法在 MathLink
模式下工作。所以我需要定义自己的函数来返回上一个输入行。我在此处
在某些情况下不起作用:
In[1]:= Unevaluated[2 + 2]
With[{line = $Line - 1}, HoldForm[In[line]]] /. (DownValues[In])
Out[1]= Unevaluated[2 + 2]
Out[2]= 2 + 2
这是因为 RuleDelayed
没有 HoldAllComplete
属性。添加这个属性就可以了:
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]
但是修改内置函数通常不是一个好主意。有更好的方法吗?
I have discovered that InString[]
does not work in MathLink
mode when sending input with EnterExpressionPacket
header. So I need to define my own function that returns previous input line. One way I have developed here
does not work in some 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 is because RuleDelayed
has no HoldAllComplete
attribute. Adding this attribute makes this 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 generally is not a good idea. Is there a better way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
看来我已经解决了这个问题。这是函数:
我刚刚从 Todd Gayley (Wolfram Research) 那里得到了关于
MathLink
模式下InString
问题的答案:编辑:
我刚刚发现我的代码不适用于带有头
Evaluate
的输入表达式。解决方案是在我的代码中将HoldForm
替换为HoldComplete
:这效果很好。另一种方法是取消对
HoldForm
的保护并在其上设置属性HoldAllComplete
。我想知道为什么HoldForm
默认没有这个属性?编辑2:
在主要问题的评论中,Leonid Shifrin提出了更好的解决方案:
有关详细信息,请参阅评论。
编辑3:
最后的代码可以通过用双
HoldForm
替换HoldComplete
来做得更好:这个想法取自 Wolfram Research 的 Robby Villegas 在 1999 年开发者大会上的演讲。请参阅 “使用未计算的表达式”笔记本发布于此处。
It seems that I have solved the problem. Here is the function:
And I just have got the answer to the question on
InString
inMathLink
mode from Todd Gayley (Wolfram Research):EDIT:
I just have found that my code does not work with input expressions with head
Evaluate
. The solution is to replaceHoldForm
byHoldComplete
in my code:This works well. Another approach would be to unprotect
HoldForm
and set up attributeHoldAllComplete
on it. I'm wondering whyHoldForm
does not have this attribute by default?EDIT 2:
In the comments for the main question Leonid Shifrin suggested much better solution:
See comments for details.
EDIT 3:
The last code can be made even better for by replacing
HoldComplete
by doubleHoldForm
:The idea is taken from presentation by Robby Villegas of Wolfram Research at the 1999 Developer Conference. See subsection "HoldCompleteForm: a non-printing variant of HoldComplete (just as HoldForm is to Hold)" in "Working With Unevaluated Expressions" notebook posted here.
我会使用
$Pre
和$Line
为此;与$PreRead
不同,它应用于输入表达式,而不是输入字符串或框形式。您所需要做的就是为其分配一个具有HoldAllComplete
属性的函数,就像我根据文档中的示例改编的函数:我使用 MathLink 对此进行了测试,其行为似乎是这样的你想要的(我省略了一些文字记录以突出重点):
I would use
$Pre
and$Line
for this; unlike$PreRead
, it's applied to input expressions, not input strings or box forms. All you need is to assign it a function that has theHoldAllComplete
attribute, like this one which I've adapted from the example in the documentation:I tested this with MathLink, and the behavior seems to be what you desired (I've elided some of the transcript to highlight the key point):
我只是找到了更简单但危险的方法:
有人知道如何保证安全吗?
I just have found simpler but dangerous way:
Does anybody know a way to make it safe?