From: Leonid Shifrin on 21 Mar 2010 03:06 Hi Leo, For one thing, DeleteDuplicates is not strictly necessary since only the first rule with the same l.h.s. applies. More generally, though, creating a wrapper only to redefine some options seems a bit of an overkill. Logically, someone who sees <foo> in your code (may be yourself a few weeks later) will not easily see the connection to <bar>. If you have several functions, and for each you would like several option configurations to pick from, I'd create something like an option configuration manager - something like this: ClearAll[setOptionConfiguration, getOptionConfiguration, withOptionConfiguration]; SetAttributes[withOptionConfiguration, HoldFirst]; Module[{optionConfiguration}, optionConfiguration[_][_] = {}; setOptionConfiguration[f_, tag_, {opts___?OptionQ}] := optionConfiguration[f][tag] = FilterRules[{opts}, Options[f]]; getOptionConfiguration[f_, tag_] := optionConfiguration[f][tag]; withOptionConfiguration[f_[args___], tag_] := f[args, Sequence @@ optionConfiguration[f][tag]]; ]; Now, here is how you could use it: ClearAll[bar]; Options[bar] = {barA -> 1, barB -> 2}; setOptionConfiguration[bar, "first", {barA -> 11, barB -> 22, fooA -> 1}]; bar[x__, OptionsPattern[]] := Module[{}, Print["barA: ", OptionValue[barA]]; Print["barB: ", OptionValue[barB]]]; bar[1, 2] barA: 1 barB: 2 withOptionConfiguration[bar[1, 2], "first"] barA: 11 barB: 22 withOptionConfiguration[bar[1, 2, barA -> "overriding_barA"], "first"] barA: overriding_barA barB: 22 With this construct, you can do some cool things like creating shortcuts such as this: first = Function[code, withOptionConfiguration[code, "first"], HoldFirst]; first(a)bar[1, 2, barA -> "overriding_barA"] During evaluation of In[876]:= barA: overriding_barA During evaluation of In[876]:= barB: 22 In this way, you can create any number of option configurations you want, and it is quite clear to anybody reading this code, what is going on. Also, you avoid the need of double - override such as your explicit options passed to <foo>: in this setup, your configuartions override Options[bar], but options explicitly passed to <bar> override both. IMO, this construct is simpler. Hope this helps. Regards, Leonid On Sat, Mar 20, 2010 at 12:45 AM, Leo Alekseyev <dnquark(a)gmail.com> wrote: > Suppose I have a function foo which is a wrapper for bar. Both of > them have certain default options. Options[foo] includes some options > that should be passed to bar, which may override some of bar's > defaults, but if they are not provided bar should always receive some > default options. > > Here are the definitions > > ClearAll[foo]; > ClearAll[bar]; > Options[bar] = {barA -> 1, barB -> 2}; > Options[foo] = {barA -> 11, barB -> 22, fooA -> 1}; > > And here is the desired output: > In[199]:= foo[] (* pass some default options to bar *) > Out[199]= bar[{barA -> 11, barB -> 22}] > > In[200]:= foo[barA -> "overriding_barA"] (* overriding the default > option barA *) > Out[200]= bar[{barA -> "overriding_barA", barB -> 22}] > > This situation commonly arises for me, and I've been using the > following implementation for foo[], which basically concatenates > supplied and default options and deletes duplicates, but I keep > thinking that there should be a better way. Is there?.. Am I missing > something obvious here?.. > > foo[opts : OptionsPattern[]] := > Module[{}, > bar[FilterRules[{opts}, Options[bar]]~Join~ > FilterRules[Options[foo], Options[bar]] // > DeleteDuplicates[#, First[#1] == First[#2] &] &]] > >
|
Pages: 1 Prev: Need larger window for Manipulate Slider Control Next: Mathematica SIG (Washington DC Area) |