2011-02-17 60 views
4

我在编写需要选项的函数时遇到了一些问题。其中一个选项值是一个函数。我有一个得到这个价值,但保持它未评估。我尝试了我可能想到的每一件事,但迄今为止没有任何工作。在Mathematica中未评估选项的值为

基本上,说明这是我的尝试:

SetAttributes[Foo, HoldRest]; 
Options[Foo] = {Blah -> None} 

Foo[x_, OptionsPattern[]] := 
    Module[{blah}, 

     blah = OptionValue[Automatic, Automatic, Blah, Hold]; 
     . 
     . 
     . 

后来,当我有:

func[a_, b_, c_] := a + b + c; 

我希望能够调用美孚与:

Foo[2, Blah -> func[1, 2, 3]] 

并且将“blah”变量(在Foo内部)进行未评估,即blah = func [1,2,3]。

感谢您提前提供的所有帮助!

编辑:

对于太长阐述的原因,我不能使用RuleDelayed(:>)。我正在尝试编写一个函数,该函数将被其他人使用,这些人不太了解Mathematica,因此他们不知道:>是。使用规则( - >)来指定选项及其值是标准方法,并且他们熟悉这一点。

所以为了进一步说明,让我们说,我试图写一个号码发生器函数,它产生的实际数量作为它的一个选项的功能:现在

Options[GenerateNumbers] = {GeneratorFunction -> None}; 

GenerateNumbers[n_, OptionsPattern[]] := 
    Module[{func}, 

     func = OptionValue[GeneratorFunction]; 
     Table[func, {n}] 
    ]  
] 

,如果我叫这个用的值作为函数如下:

GenerateNumbers[5, GeneratorFunction -> RandomReal[10]] 

这将返回5个数字是相同的列表,因为RandomReal [10]被计算一次,而不是在每一个表的迭代。我想阻止这一点。这个问题更复杂,但也是这样。

谢谢!

回答

3

您对这些选项的使用有点奇怪。如果你想传递一些包含在Hold中的表达式,为什么不在传递时将其包装在Hold中,比如Blah->Hold[func[1,2,3]]?总之,假设这个简单的定义为Foo

Foo[x_, OptionsPattern[]] := 
Module[{blah}, 
    blah = OptionValue[Automatic, Automatic, Blah, Hold]; 
    blah 
], 

你可以通过一个选项,以完成你想要的RuleDelayed而不是Rule

In[7]:= func[a_, b_, c_] := a + b + c; 

In[8]:= Foo[2, Blah :> func[1, 2, 3]] 

Out[8]= Hold[func[1, 2, 3]] 

HTH

编辑:

如果你不想要Hold缠绕,这是摆脱它的一种方法:

In[25]:= 
ClearAll[setDelayedHeld]; 
SetAttributes[setDelayedHeld, HoldFirst]; 
setDelayedHeld[lhs_, Hold[rhs_]] := lhs := rhs 

In[28]:= 
Clear[Foo]; 
Foo[x_, OptionsPattern[]] := 
Module[{blah}, 
    setDelayedHeld[blah, OptionValue[Automatic, Automatic, Blah, Hold]]; 
    OwnValues[blah]] 

In[30]:= Foo[2, Blah :> func[1, 2, 3]] 

Out[30]= {HoldPattern[blah$1018] :> func[1, 2, 3]} 

我回到OwnValuesblah表明它分配func[1,2,3]没有评估后者 - 如果这是你想要的。

4

为什么不使用RuleDelayed?

Foo[2, Blah :> func[1, 2, 3]] 

在这种情况下blah=Hold[func[1, 2, 3]]如预期的那样。

5

使用OptionsPattern的名称,然后用ListUnevaluated包装捕获的序列对象。捕捉右侧为Blah的一个很小的方法是:

SetAttributes[Foo, HoldRest]; Options[Foo] = {Blah -> None}; 
Foo[x_, opts : OptionsPattern[]] := 
Module[{blah}, 
    blah = OptionValue[Foo, Unevaluated[{opts}], Blah, Hold]; 
    blah] 

测试出来:

In[2]:= Foo[x, Blah -> (1 + 1)] 
Out[2]= Hold[1 + 1] 
+0

+1,这是一个非常有趣的想法。 – rcollyer 2011-02-18 16:45:13