2011-02-17 65 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