Mathematica Asked on February 11, 2021
I have written a Mathematica script in which I define functions and variables. Here is a vastly simplified example:
myFunA[int_Integer] := int + 1
myFunB[int_Integer] := int * 2
myFunC[int_Integer] := int - 3
myVarA = 1;
myVarB = 2;
myVarC = 3;
(In my actual script, the function and variable names vary; they do not follow the form myFunX
, myVarX
, etc.)
I would like to Clear
(or otherwise delete) all of the variables (myVarA
, myVarB
, myVarC
) but not the functions (myFunA
, myFunB
, myFunC
). Is this possible (without explicitly Clear
ing each of the many variables, since my actual script defines several dozen variables)? Thank you for your time.
Names
Here is a simple modification of the recent answer of @R.M, which is based on the definiton of a variable as a symbol which has an OwnValue
defined:
Clear @@
Select[
Names["Global`*"],
ToExpression[#, StandardForm,
Function[sym, OwnValues[sym] =!= {}, HoldAll]
] &
]
If your code is in some context other than Global`
(which is what I'd recommend), you can put that context in place of Global`
above.
As an alternative, and IMO more systematic way, you may define a custom assignment operator which you'd use when defining a variable:
ClearAll[defVar, $variables, clearVars];
$variables = Hold[];
SetAttributes[defVar, HoldAll];
defVar[def : ((Set | SetDelayed)[lhs_Symbol, rhs_])] :=
With[{result = def},
$variables = Append[$variables, Unevaluated[lhs]];
result];
clearVars[] := $variables /. Hold[vars__] :> Clear[vars];
Now, you use this as
myFunA[int_Integer] := int + 1
myFunB[int_Integer] := int*2
myFunC[int_Integer] := int - 3
defVar[myVarA = 1];
defVar[myVarB = 2];
defVar[myVarC = 3];
And then,
clearVars[]
AppendTo
Interestingly, in the line $variables = Append[$variables, Unevaluated[lhs]]
, you can not use AppendTo
instead, at least not in the form one would expect it to work. The reason is rather subtle: AppendTo
seems to be implemented in the top-level code, but more importantly, it leaks evaluation:
vars = vars1 = Hold[];
a=1;
AppendTo[vars,Unevaluated[a]];
AppendTo[vars1,Unevaluated@Unevaluated[a]];
{vars,vars1}
(* {Hold[1],Hold[a]} *)
You see that an extra layer of Unevaluated
is necessary to counter the evaluation leak.
I would think this is a wrong behavior for AppendTo
, but can not state with definiteness that this is a bug.
Which way to choose depends on the situation. The first method is fully automatic and will work best if you keep all your work in a specific context distinct from Global`
. The second way requires more discipline but works regardless of the contexts you are using.
Answered by Leonid Shifrin on February 11, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP