2
$\begingroup$

I'm currently using OptionValue inside a function, the Option I passed to the function should be cleared, then populated with the result of other operations inside the function. Creating the list and filling it now works given that it is an empty list. Clearing the list does not. I found some surprising behaviour when investigating why it wouldn't work. So suppose I look at the following:

ClearAll["Global`*"];
Options[foo] = {OutputList -> Empty};



foo[OptionsPattern[]] := 
 Module[{bar, Output},
  (* output roots *)
  bar = {1,5,10,300};

  Output = OptionValue[Automatic, Automatic, OutputList, Hold];
  Head[OptionValue[OutputList]];
  Clear[OptionValue[OutputList]];

  If[Output =!= Hold@Empty,
   Output /. Hold[o_] :> (o = bar);,
   bar]
  ]

We can see that when OptionValue[somevalue] is called, it is a symbol. But when trying to clear it, suddenly it is not a symbol anymore. I've tried various Hold constructs, but I couldn't make anything sensical out of it.

$\endgroup$
3
$\begingroup$

You can see how OptionValue is transformed by wrapping it in Hold:

foo[OptionsPattern[]] :=
  Module[{bar, Output},
    Hold[Clear[OptionValue[OutputList]]]
  ]

foo[]
Hold[Clear[OptionValue[foo, {}, OutputList]]]

OptionValue[foo, {}, OutputList] is not a Symbol and cannot be cleared. A simple way to do this is to Apply Clear to Hold[symbol]. I think you want something like this:

ClearAll["Global`*"];
Options[foo] = {OutputList -> Empty};

foo[OptionsPattern[]] := Module[{bar, Output},(*output roots*)bar = {1, 5, 10, 300};
  Output = OptionValue[Automatic, Automatic, OutputList, Hold];
  If[Output =!= Hold@Empty,
   Clear @@ Output; Output /. Hold[o_] :> (o = bar);, bar]]

(* note use of RuleDelayed to pass the output Symbol *)
foo[OutputList :> store];

(* check contents of store *)
store
{1, 5, 10, 300}

You might not actually need that as o = bar will reassign a basic OwnValues assignment without the need to Clear first.

$\endgroup$
  • $\begingroup$ Thank you for your answer. I have tried your last solution, but I'm still getting error messages, in the case where bar is a list. $\endgroup$ – 1010011010 Nov 8 at 14:46
  • $\begingroup$ In the actual function the exact output is: $\endgroup$ – 1010011010 Nov 8 at 14:47
  • $\begingroup$ During evaluation of In[1342]:= Clear::ssym: {-3.14226,-2.90282,-2.84296,-2.7831,-2.72324,-2.66338,-2.60353,-2.54367,<<35>>,-0.0300119,<<50>>} is not a symbol or a string. During evaluation of In[1342]:= Set::setraw: Cannot assign to raw object -3.14226. During evaluation of In[1342]:= Set::setraw: Cannot assign to raw object -2.90282. During evaluation of In[1342]:= Set::setraw: Cannot assign to raw object -2.84296. During evaluation of In[1342]:= General::stop: Further output of Set::setraw will be suppressed during this calculation. $\endgroup$ – 1010011010 Nov 8 at 14:47
  • 1
    $\begingroup$ @101 Please notice that I pass the option value using :> rather than ->; using the latter would lead to the kind of error you quote. I should have made that more clear. $\endgroup$ – Mr.Wizard Nov 8 at 14:51
  • 1
    $\begingroup$ Yes, I believe omitting RuleDelayed was the problem... Cheers $\endgroup$ – 1010011010 Nov 8 at 14:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.