Elegant manipulation of the variables list
I think that "elegant" should be syntax as close to the normal handling of symbols as possible.
I shall define a function, unimaginatively named bump
, that has a syntax similar to Part
but which allows operations on symbols by way of Unevaluated
and UpSet
. If you will consider other storage formats besides Hold[v1, v2, ...]
e.g. Hold @ {v1, v2, ...}
this might be simplified somewhat.
func_[a___, bump[lst_, idx___], b___] ^:=
func[a, #, b] & @ Part[List @@@ Unevaluated @@ {lst}, {1}, idx]
Examples:
varsH = Hold[U0[1], U0[2], B0, V0[1], V0[2]];
bump[varsH] = Range[5]; (* set all values *)
bump[varsH, 3] = 8; (* reassignment to B0 *)
varsH[[3]] (* recall B0 *)
ToString @ bump[varsH, 3] (* get name of B0 as String *)
bump[varsH, 3] =. (* Unset B0 *)
bump[varsH] =. (* Unset all *)
This works with other operations and shapes of lists too. (For consistency I think Hold @ {...}
is better but I will use the original form.)
vars2 = Hold[a, b, {c1, c2}, d];
bump[vars2, 3, 1] = 5;
bump[vars2, 3, 2] = 7;
bump[vars2, 3] += 1;
List @@ vars2 (* show the result *)
{a, b, {6, 8}, d}
bump[vars2, 3] =.;
List @@ vars2
{a, b, {c1, c2}, d}
For a simpler function upon which this one is based see:
Assigning values to a list of variable names
Here's an approach similar to Simon Woods, but using Extract
itself rather then following replacement rules:
setTo[val_] := Function[var, var = val, HoldAll]
mySymbolName = Function[var, ToString[Unevaluated[var]], HoldAll];
Which is then used as:
a[1] = b = c = 1;
vars = Hold[a, b, c];
Extract[vars, 3, setTo[42]]
Extract[vars, 3, mySymbolName]
And you can then clear the value using:
Extract[vars, 3, Unset]
a[1] = a[2] = b = c = 1;
vars = Hold[a[1], a[2], b, c];
Assign new value to the variable (the variable can already have a value)
Extract[vars, 1, Hold] /. Hold[x_] :> (x = 20)
Unset the variable
Extract[vars, 1, Hold] /. Hold[x_?ValueQ] :> (x =.)
Get the current value of the variable
Extract[vars, 1]
Get the name of the variable as String
Extract[vars, 1, Hold] /. Hold[x_] :> ToString[Unevaluated[x]]
Unset all variables
Cases[vars, x_?ValueQ :> (x =.), 1]