I'm having some problems with writing a function that takes options. One of the option values is a function. I one to get at this value but keep it unevaluated. I tried every single thing I could possibly think of but nothing worked so far.
Basically, to illustrate this is what I tried:
SetAttributes[Foo, HoldRest];
Options[Foo] = {Blah -> None}
Foo[x_, OptionsPattern[]] :=
Module[{blah},
blah = OptionValue[Automatic, Automatic, Blah, Hold];
.
.
.
Then when I have:
func[a_, b_, c_] := a + b + c;
I'd like to be able to call Foo with:
Foo[2, Blah -> func[1, 2, 3]]
And have the "blah" variable (inside Foo) to be unevaluated, i.e. blah = func[1, 2, 3].
Thanks for all the help in advance!
Edit:
For reasons that are too long to elaborate, I cannot use RuleDelayed (:>). I'm trying to write a function that will be in a package, used by other people that don't really know Mathematica, so they would have no clue what :> is. Using rules (->) for specifying options and their values is the standard way and they familiar with that.
So to further illustrate, let's say that I'm trying to write a number generator function that takes a function that generates the actual number as one of it's options:
Options[GenerateNumbers] = {GeneratorFunction -> None};
GenerateNumbers[n_, OptionsPattern[]] :=
Module[{func},
func = OptionValue[GeneratorFunction];
Table[func, {n}]
]
]
Now, if I called this function with values as follows:
GenerateNumbers[5, GeneratorFunction -> RandomReal[10]]
It would return a list of 5 numbers that are the same, since RandomReal[10] gets evaluated once and not at every iteration of Table. I want to prevent this. The problem is more complicated but it's along these lines.
Thanks!
Use a name for the OptionsPattern
and then wrap the captured sequence object with a List
and an Unevaluated
. A very minimal way of capturing the right-hand side for Blah
is:
SetAttributes[Foo, HoldRest]; Options[Foo] = {Blah -> None};
Foo[x_, opts : OptionsPattern[]] :=
Module[{blah},
blah = OptionValue[Foo, Unevaluated[{opts}], Blah, Hold];
blah]
Testing it out:
In[2]:= Foo[x, Blah -> (1 + 1)]
Out[2]= Hold[1 + 1]
Why don't you use RuleDelayed?
Foo[2, Blah :> func[1, 2, 3]]
In this case blah=Hold[func[1, 2, 3]]
as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With