Wolfram mathematica Mathematica:OptionValue是如何实现的?
内置的实现包含了一些魔力,因此Wolfram mathematica Mathematica:OptionValue是如何实现的?,wolfram-mathematica,Wolfram Mathematica,内置的实现包含了一些魔力,因此 OptionValue[name]等同于 OptionValue[f,name],其中f是 左侧的头部 转换规则,其中 出现选项值[名称] 是否有人知道如何实现类似的选项,即实现一个autoOptions[],该选项将解析为出现autoOptions[]的转换规则左侧的符号定义的选项? 为了清楚起见,我正在寻找的是一种 Options[foo]={bar->1}; foo[OptionsPattern[]]:=autoOptions[] foo[] 输出{
OptionValue[name]
等同于
OptionValue[f,name]
,其中f
是
左侧的头部
转换规则,其中
出现选项值[名称]
是否有人知道如何实现类似的选项
,即实现一个autoOptions[]
,该选项将解析为出现autoOptions[]
的转换规则左侧的符号定义的选项?
为了清楚起见,我正在寻找的是一种
Options[foo]={bar->1};
foo[OptionsPattern[]]:=autoOptions[]
foo[]
输出{bar->1}
最终的目标是执行类似于中请求的操作,而不必更改定义的RHS以外的任何内容。这里是一个简单、非常示意的版本:
Module[{tried},
Unprotect[SetDelayed];
SetDelayed[f_[args___, optpt : OptionsPattern[]], rhs_] /;
!FreeQ[Unevaluated[rhs], autoOptions[]] :=
Block[{tried = True},
f[args, optpt] :=
Block[{autoOptions}, autoOptions[] = Options[f]; rhs]] /; ! TrueQ[tried];
Protect[SetDelayed];]
您的用法:
In[8]:= Options[foo] = {bar -> 1};
foo[OptionsPattern[]] := autoOptions[]
foo[]
Out[10]= {bar -> 1}
请注意,当显式选项也被传递时,这将不起作用-考虑它们需要更多的工作,而且这通常不是一个好的实践,因为我重载了
SetDelayed
-但是您要求它,并且您得到了它 请给出一个伪代码示例,说明您的期望。也许我遗漏了什么,但为什么您不能在RHS上使用Options[symbol]
,我可以而且我确实做到了——这更像是一件好奇的事情:)另外,我还看到了一些可怕的错误,它们来自于复制代码和忘记更改这种类型的结构中的符号。谢谢Leonid。摆弄SetDelayed也是我能想到的唯一方法(尽管您的实现比我想象的要好得多),我同意这不符合良好实践的要求。尽管如此,这种模式是足够具体的,我可能会考虑……“JaNUS I实际上使用了类似的模式与代码> StEdTrime几次,而我个人并不是狂热地反对这一点。在我看来,真正重要的是,这些东西完全局限于您的用途,并且是孤立的。如果它是您自己的代码,则您始终可以自由定义自定义赋值运算符,而无需更改SetDelayed
。当您想要对某些其他代码(例如,正在加载的包)中的定义进行一些运行时修改或检查时,通常需要使用后者,而这些代码您没有直接访问权限,或者您不想直接访问或修改。@Leonid。是的,我同意。也许中缀符号中的自定义SetDelayed
,比如~def~
可以在不太难看的情况下工作。这甚至可以通过减少对尝试过的技巧的需要来进一步简化您的实现。尽管如此,我还是忍不住想知道OptionValue
是否真的由SetDelayed
@Janus处理OptionsPattern-OptionValue
中包含了一些魔力,这是毫无疑问的。虽然这些很方便,但我对它们的感觉却很复杂。较旧的OptionQ
谓词仅使用标准语言构造(规则),并且易于理解-知道参数是如何传递的以及模式是如何工作的,就足以知道选项是如何工作的。而选项值
和选项模式
则不然。我希望它们更透明,在顶级mma中实现。@Janus但由于修改SetDelayed
似乎是唯一明确的方法,我理解在系统级将其连接起来更安全,因为SetDelayed
太重要和根本,不能显式处理它。这是否是通过实际修改SetDelayed
的内置规则(code)实现的,这是一个很好的问题,我也想知道答案。