Automatic way based on 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.
Automation based on custom assignment operator
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[]
A digression: evaluation leak in 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.
Remarks
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.