Overriding system functions (was: Programming Options)
- To: mathgroup at christensen.cybernetics.net
- Subject: [mg877] Overriding system functions (was: Programming Options)
- From: wagner at bullwinkle.cs.Colorado.EDU (Dave Wagner)
- Date: Thu, 27 Apr 1995 01:49:40 -0400
- Organization: University of Colorado, Boulder
In article <3nf21g$kgm at news0.cybernetics.net>,
Allan Hayes <hay at haystack.demon.co.uk> wrote:
>
>In mg[802] JackGoldberg asks
>
>> Should (and can!) one add options to a built in command? I do
>
Some comments on Alan Hayes' example using Plot:
> prtd = MemberQ[Attributes[Plot],Protected];
> Unprotect[Plot];
> ...
> If[prtd, Protect[Plot]];
The purpose of this code fragment is to leave the Plot symbol in
the same state (w.r.t. being Protected) as it was before the code
executed. There's a slicker way to do this that is also more general.
Unprotect returns a list of the symbol(s) that it unprotected.
So the above could be accomplished by:
prtd = Unprotect[Plot];
...
Protect @@ prtd;
The big advantage to using this idiom comes when you are modifying a
few system symbols at a time. It is very compact:
prtd = Unprotect[Plot, ParametricPlot, ContourPlot, ...];
...
Protect @@ prtd;
This will protect exactly those symbols that were protected before
the call to Unprotect, and leave the rest unprotected.
Second, if you find yourself slinging options around a lot,
you might benefit from using the FilterOptions functions that
is defined in the standard package Utilities`FilterOptions`:
In:
FilterOptions[Plot, PlotPoints->25, Bogus->Never, AspectRatio->1]
Out:
Sequence[PlotPoints -> 25, AspectRatio -> 1]
You'll note that FilterOptions takes a sequence (not a list!) of
options and returns another sequence. The head "Sequence" goes away
whenever you insert a sequence into another expression. For example,
In:
{a, %, b}
Out:
{a, PlotPoints -> 25, AspectRatio -> 1, b}
Sequence is also the head of objects that match patterns like "__" and
"___". This makes FilterOptions perfect for collecting options from
one function call and pasting them into another. For example:
myPlot[f_, range_List, opts___Rule] := (* opts is a Sequence *)
Module[{mungedF, mungedR},
{mungedF, mungedR} = doMyOwnThing[f, range, opts];
(* now call the real plot *)
Plot[mungedF, mungedR, FilterOptions[Plot, opts]];
]
Both the Protect/Unprotect technqiue and FilterOptions were invented by
Roman Maeder, which should come as no surprise to anybody!
Dave Wagner
Principia Consulting
(303) 786-8371
princon at csn.net
http://www.csn.net/princon