I guess this is a duplicate but I can't find it. Here's something you may find useful:
myModule // ClearAll
myModule // Attributes = {HoldAll}
myModule[expr_] := Module[
{ spec = (
Union[ Join @@ Cases[
Hold[expr]
, s_Symbol /; Context[Unevaluated[s]] === "Global`" :> Hold[s]
, {-1}
, Heads -> False
]]
) /. Hold[spec__] :> Hold[{spec}]
}
, Module @@ (Hold[Evaluate[Unevaluated @@ spec], expr])
]
a = 1;
b = 1;
c = a + b;
f[x_, y_] := myModule[a = 3; b = 2; c = (x + y)*(a + b)];
f[1, 2]
a
b
15
1
1
Short explanation
Cases
extracts all symbols from Global`
context, could be not from System`
but then Package symbols would be used too. I know Global`
isn't always the $Context
so maybe $Context
would be better? Don't know, up to you.
It ignores head so from f[g,h]
only g
and h
will be extracted. Do you want that? Again, don't know, feel free to change it.
At the end it returns {Hold[g], Hold[h],...
then we transform this result to Hold[{g,h,...}
Module
assembling