# How to apply Set to held symbols listed in a variable?

I have a variable states that contains a list of held symbols:

states = Table[Hold@Evaluate@Unique[state], {2}]
(* {Hold[state$817], Hold[state$818]} *)


Initializing the valuse of these variables is not really a problem, I can do it as in

Evaluate@ReleaseHold@states[[1]] = Red
Evaluate@ReleaseHold@states[[2]] = Red


But I didn't manage to find a convenient way to replace the values of these symbols after the first initialization. I tried a variety of things, including the Trott-Strzebonski in-place evaluation technique.

I managed to make this almost work, but I still feel like I'm missing something. If I for example try

states[[1]] /. s_Symbol :> RuleCondition[s = Green;];


the value of the variable is correctly reassigned, but I also get the error

Set::wrsym: Symbol Hold is Protected.


which I'm guessing arises from Hold itself matching the s_Symbol condition. But if I try to make Hold not match with

states[[1]] /. s_Symbol?(Head@# =!= Hold &) :> RuleCondition[s = Green;];


the error does not go away.

What's the preferred way to handle this situation?

• Hold[var] /. Hold[s_] :> RuleCondition[s = Green;]; – Kuba Feb 21 '17 at 22:57
• Not sure why you want to use RuleCondition. Just: states[[1]] /. Hold[s_] :> Set[s, Green] should work. – Carl Woll Feb 21 '17 at 23:19

This general operation has been covered before, including:

From my answer to the last question:

func_[bump[lst_, idx___], arg___] ^:=
func[#, arg] & @ Part[List @@@ Unevaluated @@ {lst}, {1}, idx]


Applied:

states = Join @@ Table[Hold@Evaluate@Unique[state], {3}]

Hold[state$534, state$535, state\$536]

bump[states, 1] = "red";
bump[states, {2, 3}] = {"green", "blue"};

List @@ states

{"red", "green", "blue"}

bump[states, 2] = "black";

List @@ states

{"red", "black", "blue"}