Introduction
I often have the problem that in an expression, I want to change an option. If we are sure the option is not present, we could simply use Append[expression, opt -> val]. But sometimes such an expression is very long and it can be a bit of a pain to see if this option is already present.
Example
We have
Notebook[{Cell["hello", "Text"]}]
we want
Notebook[{Cell["hello", "Text"]}, Background -> LightGreen]
Mathematica has some built in functions for setting options. They are SetOptions, Option in combination with Set (which I think does the same thing as SetOptions) and CurrentValue in combination with Set. None of these seem to do what I want.
Silly things I tried
The fact that we can use Options with Set may sound promising, but although we can ask the value of an option in an expression, we cannot set it.
Example
kkkk:=f[2,q->c,z->x,zz->xx];
Options[kkkk]
Options[kkkk, q]
{q -> c, z -> x, zz -> xx} {q -> c}
But
Options[kkkk] = {q -> d, z -> x, zz -> xx}
gives an error and
Options[Unevaluated@kkkk] = {q -> d, z -> x, zz -> xx}
does something strange.
Nice function
So I have made my own function
setExpressionOptions[
head_[
a__,
b : Longest[ OptionsPattern[], 1],
Longest[(symb_ -> _) ..., 2],
d : OptionsPattern[]
],
symb_ -> val_
] := head[a, b, symb -> val, d]
Examples of use
setExpressionOptions[f[2, q -> b, z -> x, zz -> xx], q -> c]
f[2, q -> c, z -> x, zz -> xx]
setExpressionOptions[f[2, z -> x, zz -> xx], q -> c]
f[2, z -> x, zz -> xx, q -> c]
The function also works with Unevaluated
setExpressionOptions[Unevaluated[Plot[x, {x, 0, 1}]], PlotStyle -> Red]
(*a plot with a red line*)
Note that we really need Unevaluated here, otherwise the expression with head Plot evaluates to an expression with head Graphics, which does not work with PlotStyle.
Possible extension
We can define the function setOptions like this
setOptions[
x_ /; MemberQ[{NotebookObject, CellObject, FrontEndObject, InputStream,
OutputStream, Symbol, String}, Head[Unevaluated@x]], y___
] := SetOptions[x, y]
setOptions[z___] := setExpressionOptions[z]
Examples of use
setOptions[EvaluationNotebook[], Background -> LightGreen]
(*makes the background LightGreen*)
setOptions[f[1], q -> r]
f[1, q -> r]
Question
I like the functions quite a lot, but they could be better. It would be nice if we could set any number of options at once using setExpressionOptions.
Example of desired evaluation
setExpressionOptionsBetter[
Notebook[{Cell["hello", "Text"]}, Background -> LightGreen],
Background -> Cyan,
DynamicUpdating -> True
]
Notebook[{Cell["hello", "Text"]}, Background -> Cyan, DynamicUpdating -> True]
Note that SetOptions works the same way; beyond position one there are any number of Rules. That also makes integrating this case in setOptions easier.
Also I am sure I left out a lot of heads in the test in setOptions. The Q&A How can I work out which functions work with SetOptions? sounded promising for making the list more complete, but I guess it is not helpful.
Main question*: Can we add the additional functionality?
sub Question 1: Did I overlook anything and can this be done easier?
sub Question 2: Can this use of
Longestlead to bad performance? (probably no)



RuleDelayed. 3) You can specify multiple options. 4) The order of non duplicate options is preserved and duplicates are removed. 5) Inserting new options at the start is more natural. On the flip side, I personally prefer a setup wheresetOptsdoes not have a hold attribute, analogous toSetOptionsand friends. – Jacob Akkerboom Apr 28 '14 at 11:59setOpts["foo", 1 -> 2]unevaluated that can done with a simple addition. What behavior is lost in my approach that you would like to retain? Perhaps it is possible. – Mr.Wizard Apr 28 '14 at 19:07f := Interpolation[list, InterpolationOrder -> 1]andg := setOpts[f, InterpolationOrder -> 4]but your function actually works perfectly well. I just mistypedlist = RandomReal[{0, 1}, {2, 100}];(so the transpose of whatInterpolationlikes) and the interpolation call was crashing my kernel (which I don't understand at all and is extremely annoying in its own right but nothing to do with your function). So, yeah, my bad and +1. – gpap May 01 '14 at 09:07