以下是$Pre
Simon建议的基于方法的推广和$Post
Mr.Wizard建议的基于方法的推广.
在这两种情况下,一个应该设置HoldAllComplete
属性的纯函数和包裹x
通过(输入表达式)在其内部Unevaluated
,使他们与具有输入正常工作Head
小号Sequence
,Unevaluated
和Evaluate
.
比较两种版本的$Pre
基于解决方案:
f1 = Function[{x}, CheckAbort[x, Null], {HoldAll}]
f2 = Function[{x}, CheckAbort[Unevaluated@x, Null], {HoldAllComplete}]
In[3]:= f1@Sequence[1,2]
f1@Abort[]
f1@Evaluate[Abort[]]
f1@Unevaluated[1+1]
Out[3]= 1
Out[5]= $Aborted
Out[6]= 2
In[7]:= f2@Sequence[1,2]
f2@Evaluate[Abort[]]
f2@Unevaluated[1+1]
Out[7]= Sequence[1,2]
Out[9]= Unevaluated[1+1]
Run Code Online (Sandbox Code Playgroud)
可以看出,第一个版本很容易被破坏,Evaluate[Abort[]]
并且输入表达式有Head
s Sequence
和Unevaluated
.对于没有HoldAllComplete
属性的任何单参数函数通常都是如此.因为$Pre
,$Post
和朋友都是一个参数的功能之一,必须始终设置HoldAllComplete
属性给他们.
我也认为使用(没有必要)Null
的第二个参数没有问题.在我的机器上(Windows 2000下的Mathematica 7.0.1)永远不会返回.CheckAbort
Return@Null
$Abort
f2
$Post
基于解决方案也是如此.它可以概括如下:
$Post = Function[x, If[Unevaluated@x =!= $Aborted, Unevaluated@x],
HoldAllComplete]
Run Code Online (Sandbox Code Playgroud)
测试表达式:
In[14]:= Unevaluated[1+2]
Sequence[1,2]
$Aborted
Abort[]
Out[14]= Unevaluated[1+2]
Out[15]= Sequence[1,2]
Run Code Online (Sandbox Code Playgroud)
如果您不使用$Post
其他内容,或者您可以组合功能,则可以使用:
$Post = # /. $Aborted -> Null &;
Run Code Online (Sandbox Code Playgroud)
请注意,您可能会破坏程序,因为程序可能会$Aborted
在其控制流程中使用.
更强大,解决问题Alexey演示:
$Post = Function[Null, Unevaluated@# /. $Aborted -> Null, HoldAllComplete];
Run Code Online (Sandbox Code Playgroud)