正如其他人指出的那样,可以通过三种方法以一致的方式处理错误:
- 正确输入参数并设置函数运行的条件,
- 正确且一致地处理所产生的错误,以及
- 简化您的方法来应用这些步骤。
As Samsdram https://stackoverflow.com/questions/4174791/preventing-undecipherable-runtime-errors-in-mathematica/4175641#4175641指出,正确键入您的函数将有很大帮助。不要忘记:
的形式因为有时以这种形式更容易表达某些模式,例如x:{{_, _} ..}
。显然,当这还不够时PatternTest
s () and Condition
s ()是要走的路。 Samdram 很好地涵盖了这一点,但我想补充一点,您可以通过纯函数创建自己的模式测试,例如f[x_?(Head[#]===List&)]
相当于f[x_List]
。请注意,使用纯函数的&符号形式时,括号是必需的。
处理生成的错误的最简单方法显然是Off
,或者更多本地化。在大多数情况下,我们都同意完全关闭我们不想要的消息是一个坏主意,但是Quiet
当您知道自己正在做的事情会引起抱怨但在其他方面是正确的时,这会非常有用。
Throw
and Catch
有它们的位置,但我觉得它们应该只在内部使用,并且您的代码应该通过设施。可以按照与设置使用消息相同的方式创建消息。我相信可以使用以下函数构建连贯错误策略的关键, , .
Example
我的代码的一个例子是OpenAndRead
它可以防止中止读取操作时留下打开的流,如下所示:
OpenAndRead[file_String, fcn_]:=
Module[{strm, res},
strm = OpenRead[file];
res = CheckAbort[ fcn[strm], $Aborted ];
Close[strm];
If[res === $Aborted, Abort[], res] (* Edited to allow Abort to propagate *)
]
直到最近,还有使用
fcn[ file_String, <otherparams> ] := OpenAndRead[file, fcn[#, <otherparams>]&]
fcn[ file_InputStream, <otherparams> ] := <fcn body>
然而,每次这样做都很烦人。
这是哪里贝利撒留 https://stackoverflow.com/questions/4174791/preventing-undecipherable-runtime-errors-in-mathematica/4176010#4176010通过创建一种可以一致使用的方法,解决方案就可以发挥作用。不幸的是,他的解决方案有一个致命的缺陷:你失去了对语法突出显示功能的支持。所以,这是我想出的一个替代方案OpenAndRead
从上面
MakeCheckedReader /:
SetDelayed[MakeCheckedReader[fcn_Symbol, symbols___], a_] :=
Quiet[(fcn[file_String, symbols] := OpenAndRead[file, fcn[#, symbols] &];
fcn[file_Symbol, symbols] := a), {RuleDelayed::"rhs"}]
有使用情况
MakeCheckedReader[ myReader, a_, b_ ] := {file$, a, b} (*as an example*)
现在,检查定义myReader
给出了两个定义,就像我们想要的那样。但在函数体中,file
必须被称为file$
。 (我还没有弄清楚如何按照我的意愿命名文件 var 。)
Edit: MakeCheckedReader
其工作原理是其本身不做任何事情。相反,TagSet
() 规范告诉 Mathematica 当MakeCheckedReader
是在 LHS 上找到的SetDelayed
然后将其替换为所需的函数定义。另外,请注意使用Quiet
;否则,它会抱怨模式a_
and b_
出现在等式的右侧。
Edit 2: Leonid https://stackoverflow.com/users/565518/leonid-shifrin指出如何能够使用file
not file$
定义检查的读者时。更新后的解决方案如下:
MakeCheckedReader /:
SetDelayed[MakeCheckedReader[fcn_Symbol, symbols___], a_] :=
Quiet[(fcn[file_String, symbols] := OpenAndRead[file, fcn[#, symbols] &];
SetDelayed @@ Hold[fcn[file_Symbol, symbols], a]),
{RuleDelayed::"rhs"}]
更改的原因在此进行了解释answer https://stackoverflow.com/questions/6236458/plot-using-with-versus-plot-using-block-mathematica/6236808#6236808他的。定义myReader
,如上所述,并检查其定义,我们得到
myReader[file$_String,a_,b_]:=OpenAndRead[file$,myReader[#1,a_,b_]&]
myReader[file_Symbol,a_,b_]:={file,a,b}